Nokia schließt Verkauf der Mobiltelefonsparte an Microsoft ab

Mit Wirkung zum 25. April 2014 wird die Übernahme der (ehemaligen) Nokia-Mobiltelefonsparte durch Microsoft abgeschlossen.

Damit kommt eine merkwürdige Entwicklung zum Abschluss, die unabhängig von der juristischen Fragestellung sehr nach Korruption oder zumindest dubiosen Geschäften aussieht, weil der ehemalige Nokia-CEO recht offensichtlich mehr die Interessen seines ehemaligen Arbeitgebers Microsoft als seines dann aktuellen Arbeitgebers Nokia vertreten hat. Unter Elop (und nicht davor) ist Nokia vom Marktführer bei Smartphones zu einem Nischenanbieter geworden. Das mag sich mit den Symbian-Geräten abgezeichnet haben, aber es hätte plausible Ansätze gegeben, zumindest in der Spitzengruppe zu bleiben, wenn Meego oder Android als System eingesetzt worden wäre. Nun hat Samsung die Spitzenposition übernommen, die Nokia einst hatte. Apple war weltweit nie die Nummer eins und wird es wohl auch mit an Sicherheit grenzender Wahrscheinlichkeit nie werden. In einzelnen Märkten, z.B. in der Schweiz, haben sie aber immer noch große Marktanteile.

Und die innovativsten ehemaligen Nokia-Mitarbeiter haben eine neue Firma Jolla gegründet, die an Nokias innovativere Zeiten anzuknüpfen versucht, und vielversprechende Produkte anbietet. Wenn Jolla sich langfristig als Nischenanbieter etablieren kann, ist das sicher ein Erfolg und eine Bereicherung für den Markt.

Microsoft will die neue Abteilung unter dem Namen „Microsoft Mobile Oy“ betreiben. Sie haben die Rechte erworben, den Namen „Nokia“ und die Social-Media-Auftritte von Nokia für eine gewisse Zeit zu verwenden. Das ist nicht ungewöhnlich bei Übernahmen. Z.B. stellt die Firma Volvo seit 1999 keine Autos mehr her, aber sie haben die entsprechenden Aktivitäten verkauft und der aktuelle Besitzer kann auch nach 15 Jahren noch die Marke verwenden. Bei Nokia/Microsoft wird das aber nur für wenige Jahre möglich sein, außer die Verträge werden für entsprechende Zahlungen verlängert.

Share Button

Elixir II

Da ich das Glück hatte, an einer halbtägigen Elixir-Schulung teilzunehmen, möchte ich das Thema wieder aufgreifen.

Elixir ist eine relativ neue Programmiersprache, die sich von der Syntax an Ruby anlehnt. Die Programme laufen auf der Erlang-VM (BEAM). Diese VM ist anscheinend restriktiver als die Java-VM und so ist Elixir von den Konzepten her auch sehr nahe an Erlang.

Grundsätzlich ist Elixir wie Erlang eine funktionale Sprache, nicht wie Ruby objektorientiert. Es gibt aber die Möglichkeit, Strukturen aus Listen und Tupeln aufzubauen und weiterzugeben. Alle diese Strukturen sind immutable. Das heißt, dass Änderungen daran stets das Original unverändert lassen und eine Kopie mit den Änderungen generieren. Im Falle von verketteten Listen funktioniert das gut, wenn man nur am Anfang ein Element hinzufügt, weil dann kein eigentliches Kopieren erforderlich ist. Fügt man am Ende etwas hinzu, muss die Liste kopiert werden, was eine aufwändigere Operation ist. Es gibt keine Schleifen, wie in den meisten herkömmlichen Programmiersprachen, sondern man verwendet stattdessen Rekursion. Endrekursion sollte bevorzugt werden, weil das intern in Schleifen umgewandelt wird. Über die Parameterliste dieser Funktion kann man einen „Zustand“ weiterreichen.

Es ist sehr einfach und auch üblich, „Prozesse“ zu generieren. Dies sind nicht OS-Prozesse, sondern Konstrukte innerhalb von Erlang, man kann etwa an Aktoren denken, wie es bei Scala und Akka genannt wird. Wenn genug Hardware-Ressourcen vorhanden sind, kann man ohne weiteres mehrere Millionen solcher „Prozesse“ gleichzeitig haben. Jeder Prozess hat seinen eigenen Speicher und kann jedem anderen Prozess mit

send(...)

Nachrichten (messages) senden. Diese werden in eine sogenannte Mailbox (eine Warteschlange / engl. Queue) des Prozesses eingefügt und von diesem mit

receive(...)

empfangen. Das typische Muster ist, dass ein Prozess mittels Rekursion in einer Endlosschleife ist und jeweils mit receive Messages empfängt und verarbeitet.

Über diese Prozesse kann man doch so etwas wie einen Zustand modellieren. Man hat einfach einen Prozess mit so einer Endlosschleife und schickt ihm „set“- und „get“-Nachrichten. Die „set“-Nachrichten ändern den Zustand, der in der Endlosschleife über die Parameter weitergereicht wird, die get-Nachrichten lösen aus, dass eine Nachricht an den Absender geschickt wird, die dieser wiederum mit receive abfangen muss.

Funktionen mit gleichem Namen werden nach der Anzahl der Parameter, nicht aber nach dem Typ der Parameter, unterschieden. Die Sprache ist dynamisch typisiert. Man kann statt ein großes „if“ innerhalb einer Funktion zu haben, diese auch für verschiedene Fälle definieren und es wird für den tatsächlichen Aufrufparameter die richtige Teildefinition gefunden.

Share Button

Numerische Typen

Es geht hier nicht um dynamische oder statische Typsisierung, sondern eher darum, was von den Programmiersprachen an Funktionalität für numerische Typen angeboten wird. Irgendeine Form der Typisierung (dynamisch oder statisch) ist natürlich erforderlich, damit das funktionieren kann. Im Extremfall reicht vielleicht sogar der Ansatz, dass durch die Funktionsnamen unterschieden wird, als welche Typen die Eingabeparameter zu interpretieren sind, was z.B. bei Assemblersprachen praktisch durchgängig so üblich ist.

Was ich bei numerischen Typen sehr wichtig finde, ist dass man die Formeln, die die Berechnung beschreiben, so hinschreiben kann, wie sie sind, also z.B.

    \[ a = b \cdot c + d \cdot e \]

oder

a = b * c + d * e

oder gerne auch

a := b (*) c (+) d (*) e

statt

a = (b * c) + (d * e),

denn „Punktrechnung vor Strichrechnung“ lernt man in der Grundschule und das sollte zumindest bei Leuten, die sich mit Quelltexten von Software beschäftigen, im Erwachsenenalter sitzen. Damit will ich nicht sagen, dass man jeweils alle Präzendenzhierarchiestufen aller verwendeten Programmiersprachen kennen sollte, aber diese her schon. Smalltalk zwingt einen zu diesen Klammern.

Noch schlimmer ist Java, wo man für die meisten numerischen Typen etwa so etwas schreiben muss:

a = b.multiply(c).add(d.multiply(e));

Da erkennt kaum jemand die Formel wieder und Fehler sind vorprogrammiert…
Für Software, die in größerem Stil Dinge tut, die mit den primitiven numerischen Typen nicht machbar sind, ist Java nicht geeignet. Andere JVM-Programmiersprachen haben Operatorüberladung und erlauben es, mit geringerem Fehlerrisiko solche Dinge zu entwickeln. Eventuell kann auch ein Präprozessor eingesetzt werden, der eine Java-ähnliche Sprache mit einer Form von Operatorüberladung in Java übersetzt.

Was vielleicht auch geht, ist statt Infix auf Postfix- oder Präfixnotation zu wechseln. Ob man da die Formeln noch erkennt, ist ein bißchen eine Gewohnheits-, Geschmacks- und vielleicht auch Fähigkeitsfrage, wobei es sicher gute SW-Entwickler gibt, die einfach nicht den Blick dafür haben, Infix-Notation oder Postfix-Notation zu erkennen. Das sieht dann mit Präfixnotation in Lisp etwa so aus:

(setq a (+ (* b c) (* d e)))

oder mit Postfix-Notation, die man von alten HP-Taschenrechnern oder von Forth oder von der Druckersprache Postscript kennen könnte etwa so:

&a
b
c
*
d
e
*
+
=

oder etwa so:

b ENTER C * ENTER d ENTER e * + STO a

Angeblich soll das verständlicher sein als die Infixnotation, sagen manche HP-Taschenrechner-Fans aus den 80er Jahren.

In diesem Blogbeitrag über Zahlen steht ein bißchen dazu, auf was sich numerische Typen beziehen können. Eine 1:1-Zuordnung ist in der Regel nicht möglich, weil selbst „unbegrenzte“ Ganzzahlen wie bei Ruby oder Lisp in Wirklichkeit durch den Speicher des Rechners begrenzt sind. Aber man kann doch eine realistische Approximation erkennen.

  Ruby Perl Python Java Scala Clojure Elixir C C++
{\Bbb N}, {\Bbb N_0} ? ? ? (unsigned long eingeschränkt da, Überlauf) (unsigned long eingeschränkt da, Überlauf)
{\Bbb Z} nativ (Integer, BigNum) BigInt ? (BigInteger eingeschränkt wegen fehlendem Operator-Überladen) BigInteger nativ nativ (externe Libraries, z.B. GMP, eingeschränkt brauchbar wegen fehlendem Operator-Überladen) externe Libraries, z.B. GMP
{\Bbb Q} Rational Math::BigRat Fraction (externe Libraries, eingeschränkt brauchbar wegen fehlendem Operator-Überladen) externe Libraries, eventuell Aufnahme in Standardlibrary geplant. nativ ? (externe Libraries, z.B. GMP, eingeschränkt brauchbar wegen fehlendem Operator-Überladen) externe Libraries, z.B. GMP
{\Bbb R} Float, LongDecimal, BigDecimal ja ? Double, BigDecimal Double, BigDecimal ? ? double double
{\Bbb C} Complex ? ? externe Libraries ohne Operatorüberladung mühsam und fehleranfällig. ? ? ? complex ?

p-adische Zahlung und endliche Körper sind wohl schon zu sehr in der Mathematik angesiedelt und selten nativ in Programmiersprachen zu finden, außer in Programmiersprachen, die gezielt eine mathematiklastige Clientel ansprechen. Dabei sind gerade endliche Körper noch recht wichtig für Kryptographie und Codierungstheorie und werden dort natürlich auch benutzt.

Am schmerzhaftesten ist wohl immer noch, dass so wenige Programmiersprachen einen guten ganzzahligen numerischen Typ in die Sprache integriert haben, der es erlaubt, mit beliebig langen Zahlen (im Rahmen von Hauptspeicher) umzugehen.

Programmiersprachen, die so etwas wie Rational als numerischen Typ kennen, lassen ein gängiges Problem erkennen. Erfahrungsgemäß werden bei längeren Rechnungen Nenner und Zähler sehr sehr groß und die Berechnung entsprechend langsam. Dass man gut kürzen kann, ist eher die Ausnahme. Daran sollte man denken und entsprechende Performance- und Lasttests machen, um zu sehen, ob man in Laufzeit- und Speicherprobleme gerät.

Share Button

Shift- and Rotation Functions

Deutsch

In a comment to Carry Bit: How does it work the question about shift and rotation functions has been asked. Which exist and how they work exactly depends off course on the CPU architecture, but I will try to give a high level overview anyway.

The following aspects have to be considered:

  • 8, 16, 32, 64,… Bit: How many Bits are affected by the operation?
  • Shift vs. Rotate: Shift moves bits to the left or right, filling in 0 or 1 in the positions that get freed by this. The bits that get shifted out usually go to the carry bit, so the last one of these wins, if the shift is done by more than one bit. Rotation means what some English knowledge suggests: The bits shifted out are moved in on the other side.
  • ROL and ROR vs RCL and RCR: Rotation through Carry (RCL or RCR) means that the carry bit participates as bit 9., 17., 33. or 65. ROL and ROR leave the carry bit alone, at least do not use it as input.
  • Logical vs. Arithmetic Shift: This deals with the „sign“. For arithmetic Shift the number is considered to be signed in two’s complement. Therefore right shift does not necessarily introduce a 0 as new most significant bit, but depending on the sign introduces a 0 or a 1.

Current CPUs have barrel shifts or something like that so shift and rotate operations by more than one bit position are fast. This has been around for decades and is not at all new.

How the commands are called exactly and possibly some details about there operations depend on the CPU architecture.

Examples (8 bit) for shifting and rotating by one bit position:

Vorher (Carrybit in Klammern)ROL
(rotate left)
RCL
(rotate left through carry)
ROR
(rotate right)
RCR
(rotate right through carry)
ASL / SHL
(arithmetic/logical shift left)
SHR
(logical shift right)
ASR
(arithmetic shift right)
00000000 (0)00000000 (0)00000000 (0)00000000 (0)00000000 (0)00000000 (0)00000000 (0)00000000 (0)
00000000 (1)00000000 (1)00000001 (0)00000000 (1)10000000 (0)00000000 (0)00000000 (0)00000000 (0)
00000001 (0)00000010 (0)00000010 (0)10000000 (0)00000000 (1)00000010 (0)00000000 (1)00000000 (1)
00000001 (1)00000010 (1)00000011 (0)10000000 (1)10000000 (1)00000010 (0)00000000 (1)00000000 (1)
10000000 (0)00000001 (0)00000000 (1)01000000 (0)01000000 (0)00000000 (1)01000000 (0)11000000 (0)
10000000 (1)00000001 (1)00000001 (1)00000001 (1)11000000 (0)00000000 (1)01000000 (0)11000000 (0)
11111111 (0)11111111 (0)11111110 (1)11111111 (0)01111111 (1)11111110 (1)01111111 (1)11111111 (1)
11111111 (1)11111111 (1)11111111 (1)11111111 (1)11111111 (1)11111110 (1)01111111 (1)11111111 (1)

These shift and rotate operations are needed to express multiplications by powers of two and division by powers of two. In C, C++, C#, Perl, Java and some other porgramming languages these operations are included and written as „<<" (for ASL or SHL), ">>“ (for SHR) and „>>>“ for ASR.

Share Button

Shift- und Rotationsfunktionen

English

Im Kommentar zu Carry Bit: How does it work ist nach den Shift- und Rotationsfunktionen gefragt worden. Welche es genau gibt, hängt natürlich von der Prozessorarchitektur ab, aber grundsätzlich muss man die folgenden Aspekte beachten:

  • 8, 16, 32, 64,… Bit: Wieviele Bits sind von der Operation betroffen?
  • Shift vs. Rotate: Beim Shift werden an einer Seite Bits als 0 oder 1 ergänzt und auf der anderen Seite wandern sie in das Carry-Bit, beim Rotieren werden Bits im Kreis rotiert, die herausfallenden Bits vom einen Ende werden am anderen Ende wieder eingefügt.
  • ROL und ROR vs RCL und RCR: Beim Rotieren durch Carry wird das Carry-Bit als 9., 17., 33. oder 65. Bit miteinbezogen.
  • Logical vs. Arithmetic Shift: Bezieht sich auf die Vorzeichenbehandlung. Für arithmetic Shift wird die Zahl als vorzeichenbehaftet im Zweierkomplement gelesen wird. Deshalb wird beim Right-Shift nicht zwingend eine 0 als höchstwertiges Bit eingefügt, sondern je nach Vorzeichen eine 0 oder eine 1.

Heutige CPUs haben Barrelshifter oder etwas vergleichbares eingebaut und können deshalb auch Shift- und Rotate-Operationen um mehr als eine Bit-Position schnell ausführen.

Wie die Befehle genau heißen, und welche es gibt, hängt vom Prozessor ab:

Beispiele (8 Bit), Verschiebung oder Rotation nur um eine Bitposition:

Vorher (Carrybit in Klammern)ROL
(rotate left)
RCL
(rotate left through carry)
ROR
(rotate right)
RCR
(rotate right through carry)
ASL / SHL
(arithmetic/logical shift left)
SHR
(logical shift right)
ASR
(arithmetic shift right)
00000000 (0)00000000 (0)00000000 (0)00000000 (0)00000000 (0)00000000 (0)00000000 (0)00000000 (0)
00000000 (1)00000000 (1)00000001 (0)00000000 (1)10000000 (0)00000000 (0)00000000 (0)00000000 (0)
00000001 (0)00000010 (0)00000010 (0)10000000 (0)00000000 (1)00000010 (0)00000000 (1)00000000 (1)
00000001 (1)00000010 (1)00000011 (0)10000000 (1)10000000 (1)00000010 (0)00000000 (1)00000000 (1)
10000000 (0)00000001 (0)00000000 (1)01000000 (0)01000000 (0)00000000 (1)01000000 (0)11000000 (0)
10000000 (1)00000001 (1)00000001 (1)00000001 (1)11000000 (0)00000000 (1)01000000 (0)11000000 (0)
11111111 (0)11111111 (0)11111110 (1)11111111 (0)01111111 (1)11111110 (1)01111111 (1)11111111 (1)
11111111 (1)11111111 (1)11111111 (1)11111111 (1)11111111 (1)11111110 (1)01111111 (1)11111111 (1)

Diese Shift- und Rotate-Operationen braucht man vor allem, um Multiplikation mit Zweierpotenzen und Division durch Zwierpotennzen auszudrücken. In C, C++, Perl, Java und einigen anderen Programmiersprachen gibt es diese Operationen „<<" (für ASL oder SHL), ">>“ (für SHR) und „>>>“ für ASR.

Share Button