Why Opera switching to Blink (WebKit) was the blunder of a century

Despite the fact that the switch to the Blink rendering engine was supposed to be an “under the hood” change, it’s clear that this switch is in fact a total rewrite. None of the Opera exclusive features have made it into Opera Next. It doesn’t matter how good you remake the browser, the current users want their old work flow. It will probably take several years to partially re-implement the features that the old version had. In the end, those features will not be delivered hundred percent even years down the line. Current 12.x users will keep using 12.x for as long as they can, which means that eventually it’s going to become a legacy browser that will no longer be supported by major JS frameworks. The newest Opera versions will still be largely a UI for Chromium.

I believe this fits under what Joel Spolsky wrote in Things You Should Never Do, Part I. Opera is throwing away the entire Presto engine. That means they won’t be able to differentiate themselves from Chrome for several years, which means that Opera users will have the option between a soon-to-be-legacy browser and basically Chromium with a different UI.

What is the benefit of using Opera 15 over just plain Chromium? Because they removed some features like bookmarks people are supposed to change how they work to accommodate the opinion of some guy who thought this was a good idea? I don’t even care if the new feature is a hundred times better than bookmarks, people know how to use bookmarks so they want their bookmarks. The reason why people tend not to switch to a new browser is because they are so used to the UI and features their browser has that it makes it difficult. Opera Link keeps your bookmarks synced, but there is no way to transfer them to Opera 15. This means that there is no continuity to the new browser, so Opera effectively killed Opera 12.x and started from scratch. They will have to fight with EVERY other browser maker for their desktop market share because it’s just as hard to switch to Opera 15 as it is to switch to Firefox. You have none of your search engines, bookmarks, customized UI/menus, shortcuts, custom mouse gestures, etc.

The correct thing for Opera Software to do was to open source Presto so that the development could keep up with Blink and Gecko. What Opera Software has done instead is to become irrelevant.

Advertisements

Show more/show less functionality with jQuery

I looked at the code at jQuery More/Less Text and I think this is a pretty good solution. Depending on the height of the box, the contents either hide the overflow and show a “Show More” button or they show the overflow and show a “Show Less” button.

The post by Stu Green also shows how to hide this button when contents fit into the box. However, I need to explain how to do this yourself. Your HTML should be:

<div class="showmore">
    <div class="moreblock">
    	<p>The Content</p>
    </div>
</div>

Your JS function should be:

function showMore() {
    // The height of the content block when it's not expanded
    var adjustheight = 55;
    var moreText = "Read more...";
    var lessText = "Read less...";

    $(".showmore > .moreblock").each(function(){
        if ($(this).height() > adjustheight){
            $(this).css('height', adjustheight).css('overflow', 'hidden');
            $(this).parent(".showmore").append('<p class="continued">&hellip;</p><a href="#" class="adjust"></a>');
            $(this).parent(".showmore").find("a.adjust").text(moreText);
            $(this).parent(".showmore").find(".adjust").toggle(function() {
                $(this).parents("div:first").find(".moreblock").css('height', 'auto').css('overflow', 'visible');
                $(this).parents("div:first").find("p.continued").css('display', 'none');
                $(this).text(lessText);
            }, function() {
                $(this).parents("div:first").find(".moreblock").css('height', adjustheight).css('overflow', 'hidden');
                $(this).parents("div:first").find("p.continued").css('display', 'block');
                $(this).text(moreText);
            });
        }
    });
}

then you just call showMore() somewhere. Usually it will be when the document is ready, but sometimes you’ll do this in the callback after dynamically loading content. I hope this helps.

https://www.cityblis.com/ uses a similar approach ported to the newest jQuery (toggle has been deprecated)

Binary floating point numbers vs. Scaled Decimals

So far I haven’t seen anyone answer this correctly.

In Javascript (or in C and Java, for that matter) 0.1+0.1 == 0.2 is true then what does 0.1+0.2 == 0.3 evaluate to? The answer surprises most people, because it’s false. Try it right now, go to your browser’s address bar and type in javascript:alert(0.1+0.2); and you’ll get 0.30000000000000004 and that’s not 0.3, is it?

This is because the fractions in Java, C or Javascript are binary floating point fractions. This means that when converting to decimal numbers (the numbers we type by hand) there’s a loss of precision. So 0.1+0.1 happens to be correct, but 0.1+0.2 happens to have a small error. Notice that using more precision wouldn’t help the problem, it doesn’t matter how many zeroes we get before we get the 4, the == operator will still say the two numbers are not equal.

The representation of 0.1 in binary is 0.000(1100) where parentheses mean repeating. This is because diving by 5 in binary numbers yields a repeating fraction, kind of like diving by 3 in the decimal world. So depending on how many bits we leave for the exponent vs. the significant it changes at which point we cut the repeating fraction off. As we saw, this leads to inaccurate representations of decimal numbers.

So why are binary floating point numbers used at all? The only reason is speed. Specialized computer hardware uses binary floating point fractions to make quick calculations. In languages like Java there’s a specialized BigDecimal class for decimal fractions

I would argue that decimal fractions and arbitrary-precision arithmetic should be the default for a general use programming language. Binary floating point numbers should be accessed in a more awkward way, not the other way around.

Consider the following Java snippet:

BigDecimal x = new BigDecimal(0.1);

Do you see the mistake? We passed a double into the BigDecimal’s constructor, so now the value of the BigDecimal is not 0.1 at all. Again, this is very counter-intuitive because you need to pass a string into its constructor like so:

BigDecimal x = new BigDecimal("0.1");

Just the fact that there is no way to write an accurate literal for 0.1 makes a strong case for scaled decimals to be the default representation. Remember, the decimal base is the default for integers because we write numbers in the decimal base. So why should that not be the case for fractions?

Messing around in the Newspeak workspace

I’m going to attempt to continue Exploring Newspeak Workspace by writing some more code.

Let’s try using x in the workspace:

x. (*Evalutes to MessageNotUnderstood*)

So let’s try fixing it:


| x |
x. (*Evaluates to nil*)

Here I used the syntax for a slot to “declare” x. Newspeak now understands this message since a getter was generated for it. So the message x is now understood and gets the contents of x, which is now null. Note that I put a dot at the end of every statement, even though some people use it as a separator and omit it at the last statement, so | x |x is just as valid.


| x |
x::5. (*Evaluates to 5*)

Not only did the getter get generated, but also the setter. See Setter Sends in the Newspeak Language for an in-depth explanation.


| x |
x::5 raisedTo: 5+3 negated. (*Evaluates to 25*)

This shows the precedence rules of Newspeak. This is equivalent to something like here.setX(5.raisedTo(5.+(3.negated()))) and returns the value set to x.

Now let’s move on to closures. The basic syntax for closures is [ :arg1 :arg2 ... :argN | statements] where the last statement is the value of the closure. You call closures by passing the message value: with the correct number of arguments.


[5. 6.] (*Evaluates to [closure]*)
[5. 6.] value (*Evaluates to 6*)
[:a | 5. 6.] value: 4. (*Evaluates to 6*)
[:a | 5. a.] value: 4. (*Evaluates to 4*)

Newspeak has reserved words for true and false which are unique instances of classes True and False. Those classes have the methods ifTrue: and ifFalse: and also ifTrue:ifFalse:. If we inspect those classes we can see that they take closures as parameters. true ifTrue: [a] ifFalse: [b] returns a value, false ifTrue: [a] ifFalse: [b] returns b value. Because of this, Newspeak doesn’t need control structures, they are defined in the language itself! The compiler should be smart enough to optimize these anyway.

So here’s an example using these message sends:

[:a :b | a > b ifTrue: [a] ifFalse: [b]] value: 3 value: 5. (*Evaluates to 5*)

This closure gives us the bigger of the two numbers. We can even assign it to a variable:

|max = [:a :b | a > b ifTrue: [a] ifFalse: [b]].|
max value: 3 value: 5. (*Evaluates to 5*)

In fact, we can even recurse inside the closure:

|fact = [:x | x < 1 ifTrue: [1] ifFalse: [x * (fact value: x - 1)]].|
fact value: 5. (*Evaluates to 120*)

Because that code is in a closure, we delay its evaluation. If we simply passed fact value: then it would infinitely recurse going into fact and never being able to resolve it. So to wrap this post up we’re going to print stuff to the Transcript which is in the Console window. Click the little cog at the top right of the window and select Show Console Window.


|fact = [:x | x < 1 ifTrue: [1] ifFalse: [x * (fact value: x - 1)]].|
platform Transcript cr; show: ((fact value: 5) printString). (*prints a carriage return and 120 in the Transcript*)

Because we don’t care about the return of the cr message (which just prints a carriage return to the Transcript) we just put a semicolon after platform Transcript cr so that we can send it another message to show some text. Note that the TranscriptStream’s show: method sends a message asString to its argument. The value we passed into the fact closure is 5 which is a SmallInteger which understands all the messages in the closure and our result is also 120, which is another SmallInteger. But SmallInteger doesn’t understand the message AsString, so we have to send the message printString which returns a string that does understand this message.


|fact = [:x | x < 1 ifTrue: [1] ifFalse: [x * (fact value: x - 1)]].|
fact value: 5.
1 to: 10 do: [:n | platform Transcript cr; show: (fact value: n); show: ' is the factorial of '; show: n]. (*prints the factorial from 1 to 10 in the transcript*)

The to:do: message executes the block passed to it with the do: keyword with the Number n and then sets n to n+1 while n is less than the stop value passed to it by the to: keyword. You can inspect this method yourself. As you inspect further, however, a lot of the methods actually get in-lined by the compiler for speed. Yet, you can appreciate how many features of the language are just message sends instead of special language constructs.

And this example is enough to show you how code in Newspeak looks like. While Newspeak is very minimalistic in its design, this doesn’t detract from its expressive power.