
Why are most browsers developed in C++? - marpalmin
http://programmers.stackexchange.com/questions/41883/why-are-most-browsers-developed-in-c
======
pcwalton
IMHO it's pretty simple: low-level performance. Even 25% slower than the
output of a good C++ compiler means a browser goes from first to last place in
many benchmarks. People expect the page to scroll at 60 FPS and that rules out
GC pauses longer than 16 ms. Browsers are a mature market and unless the
proposed replacement has the performance of C++ it's not worth the risk.
Horizontally scaling server software has greater flexibility for performance;
hence the explosion of languages on the server side while the client side is
largely confined to languages developed in the 80s.

Parallelism may be the key to disruption here however; if a new browser can
scale better to the multi-core present and future it may be worth taking a
small hit over C++ in the sequential case. That's Servo's bet (although Rust
strives for C++-level performance even in the single-threaded case).

~~~
tzs
> People expect the page to scroll at 60 FPS and that rules out GC pauses
> longer than 16 ms

How do people writing games in Java or C# deal with this? Gaming is an area
where people expect smooth, high speed performance.

~~~
eropple
_> How do people writing games in Java or C# deal with this? Gaming is an area
where people expect smooth, high speed performance._

Short, mean answer: poorly.

Longer answer: they sacrifice the benefits of managed languages. They forego
immutability and controllable object lifetimes for the use of object pooling
to prevent the garbage collector from going nuts. And many still target 30fps
in order to minimize the effects of variable latency.

I used to do this; I'm porting my stuff from XNA/MonoGame to my own
OpenGL/GLFW/OpenAL engine in C++ because I grew unsatisfied with the
performance and limitations inherent in the process. Many of the biggest
benefits of managed languages are blunted with games in other ways, too. The
CLR, for example, should be a huge boon for scripting--the DLR is a fantastic
concept, for example. But dynamic code requires codegen, and System.Dynamic
doesn't work in Xamarin's iOS product. So if you want to bring a game with
scripting from Windows/OS X to iOS, you're boned. (Java has the same problems;
Groovy, while a great scripting language, doesn't run on Dalvik or on IKVM-
over-MonoTouch. Rhino's LiveConnect doesn't work there either.)

On the other hand, I use AngelScript and expose C++ objects and methods to it,
computed statically at runtime but executable via interpreted scripts, for the
best of both worlds without breaking my back to do it. Memory management just
isn't that hard and the performance and compatibility of native code just
can't be touched right now.

~~~
rossjudson
Object pools were good JVM thinking 10 years ago. It's been a very long time
since they made any sense for memory-based objects.

Unity manages to do quite a bit with the CLR on a cross-platform basis, and
that looks like Javascript to me.

Horrors! AngelScript has Garbage Collection! But since it didn't come from the
JVM, I guess it's OK.

[http://www.angelcode.com/angelscript/sdk/docs/manual/doc_mem...](http://www.angelcode.com/angelscript/sdk/docs/manual/doc_memory.html)

> Memory management just isn't that hard

Every victim of a use-after-free just cried out in anguish. Your world weeps
at 60 fps.

Keep in mind the original question: What's a good language for implementing a
browser? The _number one_ requirement for a browser today is not performance.
It is security. A decade of effort has been put into the major browsing
engines to snatch pseudo-victory from the clutches of determined hackers. A
great deal of that effort has been necessary because of the desire for
"speed", and the fallibility of those who believe memory management "just
isn't that hard".

~~~
eropple
_> Object pools were good JVM thinking 10 years ago. It's been a very long
time since they made any sense for memory-based objects._

I guess that's why libgdx very recently added pooling, right? And (OK, it's
Dalvik, but still) why Android uses view recycling all over the place? Why
_recommended practice_ for ListView is to re-use existing objects whenever
possible?

I'm not pulling the use of pooling out of my ass here. This is _what you do_
for high-performance managed stuff, in games and otherwise. Everybody I've
ever worked with, and I've worked with some pretty heavy hitters (some of my
former coworkers at TripAdvisor are _insanely_ plugged into the Way Of The
JVM), has kept pooling in the toolbox for latency-sensitive problems.

 _> Unity manages to do quite a bit with the CLR on a cross-platform basis,
and that looks like Javascript to me._

Well, for one, it's not. It's statically typed sort-of-JScript. It bears
little relation to JavaScript; it was originally called UnityScript and the
name was changed largely for buzzword bingo purposes. (It's really very
frustrating when working in Unity, both because it's not real JavaScript but
doesn't play nicely with Boo and C# scripts a lot of the time.)

Unity also has notable performance problems for nontrivial scenes due about
50/50 to expensive creation on the front end and garbage collection on the
back end. One of the most popular Asset Store items is--wait for it--an object
pooling system.

 _> Horrors! AngelScript has Garbage Collection! But since it didn't come from
the JVM, I guess it's OK._

It does, but only if you're allocating within it. I literally never allocate
non-stack data in it. I use it as a logical glue layer within my application,
which is not garbage collected.

 _> Every victim of a use-after-free just cried out in anguish. Your world
weeps at 60 fps._

I literally can't remember the last time I hit a use-after-free in my own
code. If you understand your object lifetimes, RAII will usually (almost
always?) put you in the right place. In the worst of cases, where you've found
yourself in a thoroughly opaque situation and can bear the perf hit, you have
tools like boost::shared_ptr (though in my current project I don't use it
anywhere).

It's certainly possible to make mistakes, but it is easier to do the right
thing than most managed-languages people are willing to admit. I used to be
one. It's why I was pretty terrified of working in C++ for so long. As it
happens, I think former-me was pretty wrong about that.

 _> What's a good language for implementing a browser? The number one
requirement for a browser today is not performance. It is security._

I'm of two minds about this. Sure, security is a critical concern. But user
experience isn't to be ignored, and I really do feel that user-detectible
pauses are to be avoided at all costs. Writing better native code is, to me, a
more feasible option than an imperceptibly fast general-purpose garbage
collector.

(As an example, I grow frustrated when scrolling a big list on my Nexus 4 when
I can watch the scrolling get stuttery. In my experience, it's almost always
due to someone not following best practices and re-allocating instead of re-
using existing objects.)

~~~
tptacek
Use-after-free bugs that are so blatant that they occur in normal use are
rare, but real UAF bugs are discovered adversarially, and it is absolutely not
simple to test them or, for that matter, avoid them.

~~~
eropple
I'd certainly agree that they certainly exist in the wild but I'm less
convinced that they're particularly hard to avoid _if_ you understand the
lifecycles of what you're working on That browsers are a tough problem with a
difficult-to-internalize object lifecycle and a bunch of edge cases makes this
tougher, for sure; my stuff is games-focused and so, yeah, I have a relatively
simple problem set.

But, all things considered I'd rather Somebody Else (because Somebody Else
makes browsers, I don't) spend developer time making a fast system secure
rather than running a slightly more secure system up against the hard walls
imposed by any managed language one would care to name.

~~~
tptacek
Integer overflows, which require no mitigation other than getting a computer
to count correctly, are extremely pernicious; they pop up even in systems that
were deliberately coded defensively against them. There's an LP64 integer bug
in qmail! And that's just for counting. Avoiding UAFs requires you to track
and properly sequence every event in the lifecycle of an object --- and, in
many C++ systems, _also_ require you to count properly.

No, I don't think they're straightforward to avoid.

I think it seems straightforward to avoid memory lifecycle bugs because it's
straightforward to avoid them under normal operating conditions. But attackers
don't honor normal conditions; they deliberately force programs into states
where events are happening in unexpected ordering and frequency.

I don't even know where to begin with the idea that it's acceptable to
sacrifice a couple memory corruption vulnerabilities in the service of a
faster browser.

~~~
eropple
_> No, I don't think they're straightforward to avoid._

Fair enough, and you certainly have more experience on the topic than I do.
Thanks for the explanation.

One quibble though, and maybe it was poor phrasing on my part:

 _> I don't even know where to begin with the idea that it's acceptable to
sacrifice a couple memory corruption vulnerabilities in the service of a
faster browser._

It's not really an either/or though, right? I mean, you can protect against
some forms of attacks through a managed environment (though the environment
itself adds its own attack surface). But you trade performance to get it. A
managed language isn't going to solve all your problems, and it is going to
mess with your performance in inconsistent and essentially intractable ways.
I'm not saying "throw in a couple memory corruption vulnerabilities if it'll
make it faster", I'm saying that you can _fix_ memory corruption
vulnerabilities. You can't fix inherently slow.

------
fdej
Web browsers must be some of the most demanding applications to develop: they
have to do very many different things; they must be very efficient; they must
be very reliable; requirements change very rapidly.

If claims made by certain language X apologists are to be believed, one can
infer that language X should permit developing a web browser in shorter time
than C++, with performance within say 20% of C++ (or even superior to C++,
depending on X and the apologist), with fewer bugs, and with a more
maintainable codebase as the result. Actually delivering such a web browser
would be a rather more convincing argument than empty talk or even glorified
Fibonacci programs. Hence, I'm very much looking forward to future progress by
the Rust guys.

------
rossjudson
There are a lot of poor or outdated answers to the question (arguing a lack of
accelerated graphics, for example).

The number one reason current browsers are implemented in C++ is momentum. A
browser has a lot of parts that do a lot of things; they're big code bases.

JIT compilation technology on the JVM (and elsewhere) these days is pulling
within 20-50% of static C/C++ code.

If you were coding from scratch these days, would you start with C/C++? I
doubt it, especially when you know you can get most of the same performance
with other platforms.

By far the most important reason to choose a modern VM environment is
security. Except in a vanishingly small number of cases, everything should
_always_ be bounds checked. The "native" part of a browser should be as small
as possible, with a highly constrained and thoroughly checked API. Take away
manual memory allocation and use after free goes away. Take away pointers and
buffer overflows go away. You want as much of the browser code as possible to
be running in a managed environment.

In my opinion every line of native code carries risks that don't exist in
managed environments. Yes, properly written C code won't exhibit those
problems -- but it seems to be extraordinarily difficult to do that. Security
flaws are still being found in browsers, decades later.

And yes, security flaws exist in systems like the JVM. Those mostly come from
native code as well, but some of them are because of the design. The JVM's
"native part" is just too big. Too _much_ is done there that doesn't need to
be.

With a massive native code base it's just a huge problem to verify everything.

So Rust and Go are quite interesting. It's critically important that these
languages remove "unsafe" features from something like C/C++, and lose almost
nothing in the process.

And around the corner, environments like the JVM can auto-vectorize on the fly
([http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7116452](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7116452)),
knocking down yet another performance-parity barrier.

~~~
kintamanimatt
Performance doesn't just include CPU time, but also memory footprint. You
might eat a similar amount of processor time, but you're not going to have a
similar memory footprint with any kind of GC'd language, and if the GC happens
to be a stop the world GC, you're likely to see pauses in the browser that
will irritate the user.

Before the inevitable "memory is cheap" argument is made, I'd rather have my
client app be a good neighbor. Having a GC'd process on a client munch through
memory like it's infinite is just bad manners and makes some bad assumptions.
(On the flip side, a GC'd process that tries to be a good neighbor by freeing
memory aggressively becomes a bad neighbor in terms of CPU time, which has
additional consequences in terms of battery life.) The JVM, for example, tends
to only run its GC when it needs to. It is a horrible neighbor in this respect
because it just takes all the memory it needs and only runs its GC when it
really, really has to. This is one of the reasons it's relatively fast, but as
a consequence puts a lot of pressure on the system. In such a scenario it's
possible other processes will OOM and be killed, or the system will start
swapping memory pages, or other processes will have to run their GC more
aggressively (as V8 does in low memory conditions) which puts even more
pressure on the system. All this adds up to very selfish apps that bog down a
system and can become virtually unusable. These selfish apps are also
unsuitable for use in poorer parts of the world where incomes are lower and
additional memory is potentially unaffordable.

I think it's probably okay to take the attitude that memory is cheap when you
control the environment and you're paying for the memory, but in any other
circumstance, shipping software that gluttonously gobbles memory is probably
unacceptable and the #1 reason why C++ makes good sense as a language choice
for writing a browser.

~~~
asveikau
I found this whole discussion irritating because not a single person mentioned
that with the memory demands of a web browser that you might not want GC. You
can say all this BS about momentum but in my mind avoiding GC is probably the
best and most relevant reason in 2013. Thank you for mentioning it.

Shows how dependent on GC a large part of the community of developers have
become - they are incapable of imagining a world without it.

(PS: I am amused when people mention that being 20-50% slower is described as
fixing the performance gap.)

~~~
marpalmin
I see your point, but even if you avoid GC you have other alternatives
nowadays.

~~~
Arelius
Not really. Nothing mature. I mean Mozilla is working on Rust for exactly this
reason. But the immaturity of that is why we don't have a Rust based browser
at the moment.

Otherwise, C++ is really our only choice for a mature, modern language without
GC.

~~~
bitwize
There's C. There's Ada. There's Object Pascal. There's Objective-C. If you're
a GNOMEhead, Vala can be pressed into service.

I seriously think that anyone who finds themselves reaching for C++ to solve a
task should try Ada instead. The semantics of their code will be clearer and
their code will be more readable, therefore maintainable.

~~~
kintamanimatt
I didn't downvote you, but, oh holy crap, Ada! Free documentation is non-
existent, performance is lacking compared to C++ [-1] (yeah, yeah, benchmarks,
etc), the community is minuscule and pretty much limited to stuff like
critical real time systems (read: avionics), and the price of the books (the
complete, current ones) is a barrier to entry.[0] From what I've read of
others' experiences, there aren't many happy Ada developers. This isn't
exactly conducive to a successful FOSS project! (On a side note, I do mostly
like the language's syntax and its influence on Ruby is very obvious.)

I'm not sure anybody would use Objective-C if it weren't for Apple, any more
than people would choose to use JavaScript if it weren't for it being the only
language available in the browser.

It's a bit of a chicken and egg problem, but the one thing you really need for
a successful OSS project are developers. Do any of the Object Pascal
implementations actually have a community?

A codebase as large as a browser written in C would be a horrible,
unmaintainable mess IHMO.

[-1]
[http://benchmarksgame.alioth.debian.org/u32/ada.php](http://benchmarksgame.alioth.debian.org/u32/ada.php)

[0] [http://www.amazon.com/s/ref=nb_sb_noss_1?url=search-
alias%3D...](http://www.amazon.com/s/ref=nb_sb_noss_1?url=search-
alias%3Daps&field-
keywords=ada%20programming&sprefix=ada+p%2Caps&rh=i%3Aaps%2Ck%3Aada%20programming)

~~~
bitwize
The Ada community is actually growing. Ada has a bad rap because back in the
day Ada was a DoD requirement, which meant that vendors could ship compilers
that conformed to the spec, but otherwise sucked rocks. With the advent of
GNAT it's no longer the case that your compiler is bound to suck. I learned
Ada primarily with the help of free resources. The ARM is also free.

Granted, the sort of person who is likely to use Ada is not a l33t hax0r, but
someone who's been around the block a few times on major engineering projects.
Still, GNAT has bindings to the likes of Gtk and OpenGL, a direct result of
increasing interest in Ada outside of critical systems engineering.

 _It 's a bit of a chicken and egg problem, but the one thing you really need
for a successful OSS project are developers. Do any of the Object Pascal
implementations actually have a community?_

FreePascal/Lazarus does. It's mainly Europeans (French and Germans primarily)
who once did PC development with Turbo Pascal.

 _I 'm not sure anybody would use Objective-C if it weren't for Apple, any
more than people would choose to use JavaScript if it weren't for it being the
only language available in the browser._

I would (and do). Its Smalltalk-based object system is much easier to wrangle
than C++'s.

 _A codebase as large as a browser written in C would be a horrible,
unmaintainable mess IHMO._

Yes, point against C. C++ has the advantage that it can turn even small
codebases into horrible, unmaintainable messes. :) This is the reason why I
converted an entire game engine to Objective-C.

------
Millennium
They all have roots going back to a time when C/C++ were the "it languages"
for UI and systems development. Java was nowhere near ready for that sort of
thing; Mozilla tried anyway, but Rhino is the only thing from that project
that really took off. No other language even came close: Tcl/Tk had the UI
part, but its performance wasn't up to par, and most other languages either
didn't have the performance, or didn't have the UI capabilities, or called out
to Tk to get the UI capabilities and thus inherited Tk's problems.

Mozilla tried the low-level guts/high-level UI approach anyway, using
JavaScript because they had to implement an engine for it anyway. But it took
them a few tries to really get it right, and its false starts in this category
remain infamous to this day. The others stuck with C/C++ for everything
because it's what worked at the time, and continue because it works for them.

Mozilla's at it again with Rust, though, and that looks like it could be an
interesting project.

------
joshmoz
The Rust language is being designed to be ideal for use in building a Web
rendering engine. Mozilla's rust-based engine experiment is called Servo:

[https://github.com/mozilla/servo](https://github.com/mozilla/servo)

------
hga
Be sure and go down to the "Ask 'when' before 'why'" answer.

------
pnp
There was a browser written in Java in the past:

[http://en.wikipedia.org/wiki/HotJava](http://en.wikipedia.org/wiki/HotJava)

~~~
specialist
I rank discontinuing HotJava as one of Sun's biggest missed opportunities.

The stackexchange commenter moans about graphics performance in Java. I helped
write the Magician OpenGL bindings for Java in the '90s (the Java API side was
all me, which Sven of JOGL basically copied). My VRML browser was just as fast
(fps) as the available VRML browsers written in C/C++. With JDK 1.1.

Nowadays, Java and OpenGL go together like peas and carrots. Exhibit A is
MineCraft.

A good buddy of mine does all his projects in Java and OpenGL. The latest is
the awesome 2D skeletal animator called Spine at
[http://esotericsoftware.com](http://esotericsoftware.com). I couldn't imagine
him doing it on top of any other stack.

~~~
eropple
_> My VRML browser was just as fast (fps) as the available VRML browsers
written in C/C++. With JDK 1.1._

With respect, I find your claims dubious. I would certainly buy that your top
framerate was competitive. I also expect that your framerate was significantly
more stuttery and inconsistent due to garbage collection (or else written in
such a devolved form of Java that you really might as well write C++ anyway).

The problem is not Java's execution speed. It's that garbage collection is the
death of responsiveness.

 _> Nowadays, Java and OpenGL go together like peas and carrots. Exhibit A is
MineCraft._

Minecraft's performance characteristics are pretty bad for the fairly trivial
rendering work being done. (It's improved, but it's still not great.) And
writing code with LWJGL/JOAL is gross relative to similar code in C++--I have
done both. You don't _get_ anything for tying yourself to the JVM except, in a
weird and mostly self-destructive way, the 'freedom' from understanding your
object lifetimes and deterministic destruction.

I've used libgdx and XNA/MonoGame extensively and have gone back to C++
because both are fairly limited in their usefulness. libgdx helps by hiding a
lot of nasty API issues--and Mario and company are super good at what they do
--but what it gives you is generally taken away by the limitations of the JVM
in a client context (limited platform support, the infuriating Dalvik/Hotspot
divide, That Frigging GC Again...). Writing up some pretty minor glue code
between windowing, input, audio, and graphics isn't that bad. And, perhaps
more importantly, you'll actually understand how it works. (I've spent the
week fighting with OpenAL. I'm glad I did. I've learned a lot and can
recognize the failure cases and can do something about them.)

 _> A good buddy of mine does all his projects in Java and OpenGL. The latest
is the awesome 2D skeletal animator called Spine at
[http://esotericsoftware.com](http://esotericsoftware.com). I couldn't imagine
him doing it on top of any other stack._

Spine's pretty impressive, but there's not much in it you couldn't do with
ease with Cocoa/Obj-C[++] or Qt or even WPF and .NET. It's also a misleading
example, though, because tooling generally has much looser latency
requirements than user software and so the severe weaknesses of JVM client
applications are less readily apparent than in an application that needs to
hit 60fps all day every day.

~~~
specialist
_expect that your framerate was significantly more stuttery and inconsistent
due to garbage collection_

Static scenes, simple eventing. Compile the screen graph to meshes, load
textures, then move the camera around. No stutter.

The trick is to avoid the GC, not thrash the heap, don't create a lot of
short-lived objects.

Implementing LOD would have sped up my browser quite a bit.

The other idea was to compile VRML's DEF prototypes to Java byte code,
avoiding VRML engine overhead, in which case my Java would have smoked C/C++.

My conclusion was not that my stupid simple browser was amazing, but rather
the "native" C/C++ implementations were terrible. By comparison, my browser
was about 5 times faster than LiquidReality, another Java-based browser.

~~~
rossjudson
And these days you can go ahead and create quite a few short-lived objects
without worrying about it, as long as they're elided by escape analysis.

With judicious use of off-heap memory for regular structures it's simple to
erase much of the crap in the heap, and reduce already-tiny GC times even
further.

Never dropping a frame is another goal entirely, though, and for that I still
believe you need a separated rendering/animation mechanism.

------
thethimble
Interesting. With the recent influx of Go rewrites, I wonder if anyone would
consider writing a browser in Go just as an experiment.

~~~
redcircle
I rewrote quite a bit of the Chromium browser in Go, achieving a 10x reduction
in lines of code (I stopped this project before I could reliably evaluate
performance). Since Chromium uses a multi-process model, this was pretty easy:
I implemented the Chromium IPC protocol in Go (I wrote a Chromium utility to
emit a JSON description of the IPC protocol), and then told the privileged and
unprivileged Chromium processes to use my Go subprocess rather than the
original logic. My Go logic ran on both Windows and Mac OS X.

~~~
touristtam
Mind sharing if you have the code public ? :)

~~~
redcircle
Belongs to my employer :(

Also, when I said 'quite a bit', I was thinking about the data-plumbing logic
--- not UI and WebKit logic. It doesn't really make sense to rewrite WebKit.

------
gte910h
Most browsers are developed in C++ because for the timeframe in which the
projects started, C++ was the performant answer

~~~
RogerL
It still is.

Consider, not just PC based browsers, but the one on your phone. Every JIT
compile costs watts, not just time. There's a relatively large push to go back
to C++ because of this (power usage). 20% reduced performance may not be
noticable as far as user interaction goes, but it is sure noticed in terms of
"my battery just died!".

It's nice to have a common code base. C++ across multiple platforms reduces my
cost, even if I have to pay for good programmer that understand the use of
things like smart pointers.

~~~
gte910h
The browser in my phone is part Objective C and part C++, as part of the
project descended from Konqueror, via WebKit. I'd contend the C++ parts are
C++ for legacy reasons, aka, "It was the performant solution at the time KHTML
was written".

Very little mobile phone software these days is written in cross platform C++,
of that it's mostly games. Most iPhone software is still written in Objective
C, most Android software is still written in Java. For cross platform code,
I'd say Xamarin or Unity C#, or Adobe's product line both are still beating
out C++, even counting the games.

Chrome is about 40% C++, and is now the default browser for android.

C#/Xamarin would probably be what I'd standardize on if going for a true cross
platform non-game app. Javascript/Unity3D or C+/Unity3D would probably be what
I standardized on for games, with Futile being looked at hard for 2D games.

Companies with a huge existing codebase (e.g. EA) likely find porting an
existent engine cheaper than writing a new one, and will of course stick with
their historical C++

~~~
oscargrouch
>Chrome is about 40% C++, and is now the default browser for >android.

Chrome is 100% C++. Did you ever sync its source code from the repo? (i wonder
what the other 60% are in your opinion, Js?)

edit: to be fair there are a little of objective-c and java just to glue with
mac/ios and android

~~~
gte910h
[http://www.ohloh.net/p/chrome](http://www.ohloh.net/p/chrome)

The metric is probably off from the automated
calculator.[http://www.ohloh.net/p/chrome](http://www.ohloh.net/p/chrome) It's
likely counting the .h files as C

~~~
oscargrouch
this 40% metric could only be true of they are counting the third-party (with
ffmpeg, webkit, etc) but then we cannot say this is chrome..

also there are a lot of tools written in python(gyp, grit, ninja etc).. but
this dont get into the executable or libraries.. so i would not count (at
least in the perspective of this thread) as the chrome itself. since those
tools are used in other projects as well and come only with the source code to
build things (it would be like to count the gcc compiler as part of the
source)

------
marpalmin
Maybe a more interesting question is: Would you use C/C++ to develop a browser
today?

~~~
shmerl
Probably yes, if it's C++11 and UI is in Qt/QML for example.

------
wisty
Why a C like language? Power. Browsers are CPU and memory hogs, and C is
simply the best way of squeezing out more performance.

Why an OO language? Well, while OO is overused, a HTML document looks a lot
like a bunch of objects, doesn't it?

------
shmerl
Why not? What other high performance languages were out there (besides C) when
these browsers were created? New browsers can be written in different
languages (for example Rust).

------
halayli
low level performance and control with a lot of abstraction features.

------
AsymetricCom
Because what else would you write it in?

