Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Saturday, November 8, 2014

Android: The import javax.annotation cannot be resolved


I was trying to compile some code from AOSP (Android Open Source Project), and I ran into this error:

The import javax.annotation cannot be resolved

Caused by this code:

import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.ThreadSafe;


The solution was actually really easy:
  1. Go here:
    http://mvnrepository.com/artifact/com.google.code.findbugs/jsr305

  2. In the Version column click on the latest version number

  3. Click Download ( JAR )

  4. Copy the downloaded JAR file to the libs folder in your Android project (create the libs folder if it doesn't already exist).

Wednesday, January 23, 2013

Enforcing Active Directory password history when resetting passwords using PHP

The code:

$ctrl1 = array(
    // LDAP_SERVER_POLICY_HINTS_OID for Windows 2012 and above
    "oid" => "1.2.840.113556.1.4.2239",
    "value" => sprintf("%c%c%c%c%c", 48, 3, 2, 1, 1));
$ctrl2 = array(
    // LDAP_SERVER_POLICY_HINTS_DEPRECATED_OID for Windows 2008 R2 SP1 and above
    "oid" => "1.2.840.113556.1.4.2066",
    "value" => sprintf("%c%c%c%c%c", 48, 3, 2, 1, 1));
if (!ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array($ctrl1, $ctrl2))) {
    error_log("ERROR: Failed to set server controls");
}

$result = ldap_mod_replace($ds, $dn, $entry);
...


Details:

There are a couple of ways to reset Active Directory passwords using LDAP:
  1. A delete operation on the unicodePwd attribute immediately followed by an add, which is a password change

  2. A modification of the unicodePwd attribute, which is considered an administrative password reset
When doing the latter, password history requirements may not be enforced. Apparently this is expected behavior. The solution is a server control:
  1. First, the control must be available on the server. It's present in Windows Server 2008 R2 Service Pack 1 and above. It can also be installed in 2008 R2 using this hotfix: http://support.microsoft.com/?id=2386717

  2. Next, the client must use the control to tell the AD server to enforce password history requirements.
If you happen to be doing this in PHP, the solution for the second part is the code I've posted. The tricky part was to get the BER encoding for the value correct.

I put both controls (the new one as well as the deprecated one) in my code and also didn't set the iscritical flag (which defaults to false) in order to make the code as flexible as possible.

In case you're looking to implement a solution to reset AD passwords using PHP, you may find these helpful:

Tuesday, August 28, 2012

Android: can't upgrade read-only database from version 0 to 1

Solution:

If you have named one of your SQLite tables "default", change the name to something else.

Details:

So I was poking around with Android programming the other day, and I ran into this error:

04-12 14:35:09.779: ERROR/AndroidRuntime(790): Caused by: android.database.sqlite.SQLiteException: Can't upgrade read-only database from version 0 to 1: /data/data/com.example.test/databases/mydatabase.db
04-12 14:35:09.779: ERROR/AndroidRuntime(790): at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:170)


The line causing the error was simply calling SQLiteOpenHelper.getReadableDatabase():

SQLiteDatabase db = dbHelper.getReadableDatabase();

I finally narrowed it down to the database table name I was using: "default". As soon as I changed the table name, it worked fine. In fact, I simply changed it from "default" to "default1".

Just to be clear, I wasn't doing anything fancy. I was using pretty basic code to create the database:

public class DatabaseHelper extends SQLiteOpenHelper {
    public static final String DB_TABLE_NAME = "default";
    ...
    public static final String DB_TABLE_CREATE =
        "CREATE TABLE " + DB_TABLE_NAME...


It doesn't appear to be a SQLite thing, because according to their documentation the only reserved table names begin with "sqlite_". So it appears to be an Android issue, and as far as I can tell it isn't documented.

I checked the database after I changed the name, and the "default" table was never created either, so I'm not sure why it wouldn't work:

sqlite> .tables
android_metadata default1


A bug, perhaps?

Wednesday, August 15, 2012

Cross-platform mobile development: PhoneGap + Enyo



If you want to develop a mobile application, but don't want to have to rewrite it for every platform you want to develop for (Android, iOS, etc.), PhoneGap is what you want. It allows you to develop applications using web technologies (HTML, CSS, JavaScript), and then deploy them to a large number of platforms, such as Android and iOS. It has APIs that let you interface directly with the mobile device's hardware (camera, GPS, accelerometer, you name it). It's even been approved by Apple, and we all know what a feat that is ;)

Undoubtedly you'll want a nice framework that gives you all the UI widgets you're used to: layouts, spinners, popups, progress bars, etc. That's where Enyo comes in. Enyo was actually the JavaScript framework that was part of WebOS. Since WebOS has been open-sourced, so has Enyo. I would recommend Enyo over other JavaScript frameworks like jQuery Mobile and Sencha; see here for some reasons why: Enyo+PhoneGap Vs jQueryMobile+PhoneGap

There are already some apps out there using this approach. Here are a couple for android:
I've even done some playing around with phonegap and the enyo samples myself. I put it in github in case it's of any interest:
https://github.com/bmaupin/junkpile/tree/master/java/testing/android-phonegap-enyo-test

The screenshots in this post are from that code, and you can see more here:
https://github.com/bmaupin/junkpile/tree/master/java/testing/android-phonegap-enyo-test/screenshots

Enjoy!

Tuesday, June 5, 2012

Eclipse Subversive plugin out of Java heap space

Solution:

Use the JavaHL SVN Connector instead of SVN Kit. to install the JavaHL Connector:
  1. In eclipse go to Help --> Install New Software...

  2. Work with: --> choose the community.polarion.com update site

  3. Expand Subversive SVN Connectors

  4. Choose the JavaHL version corresponding with your version of subversion

  5. Click Next, and then follow the instructions to complete installation

  6. Window --> Preferences --> expand Team --> select SVN --> select the SVN Connector tab --> change the SVN Connector to JavaHL --> OK
There are additional steps for completing the JavaHL installation. Subversive doesn't seem to have any helpful documentation regarding this, but Subclipse does:
http://subclipse.tigris.org/wiki/JavaHL

In Linux (elementary, Ubuntu, Debian), you can do this to finish the installation:
  1. Install libsvn-java:
    sudo apt-get install libsvn-java

  2. Then edit eclipse.ini (located in /etc/ if you installed eclipse from a package or in the eclipse folder you extracted if you downloaded it from the eclipse website), and add the following line after the -vmargs line:
    -Djava.library.path=/usr/lib/jni

    For Ubuntu 12.04 64-bit, the line should be:
    -Djava.library.path=/usr/lib/x86_64-linux-gnu/jni/

  3. Restart Eclipse

Details:

So I recently switched to Subversive from Subclipse as my SVN plugin in Eclipse. I was checking out one of my repositories (a pretty big one), and I got this error:

Checkout operation for 'https://svn.example.com/myproject' failed.
Java heap space


I have 1 GB of java heap space given to Eclipse (-Xmx1024m in /etc/eclipse.ini), and I don't think I've run out yet, but I went ahead and upped it to 1.5 GB. I got the same error. 2 GB--same error. I tried again with 2 GB of heap space, closing all perspectives to save memory, and it finally worked.

I new something wasn't right, but at first I couldn't find anything in Google. I kept searching, and finally found this:
http://www.eclipse.org/forums/index.php?t=msg&goto=559537&S=9c09f002ceb108176748012e60540921

Essentially the problem is a bug with the SVNKit SVN connector. There are two connectors available:
  • SVNKit
    • Pros: easier to install
    • Cons: possibly buggier, because it's a Java reimplementation of Subversion
  • JavaHL
    • Pros: more stable, because it's a wrapper around the native subversion C code
    • Cons: a little more work to set up
The solution, as mentioned above, is to use the JavaHL connector, because this problem is caused by a bug in the SVNKit connector.

Thursday, April 19, 2012

problems overriding android compatibility methods

I had a class that extended android.support.v4.app.FragmentActivity. I wanted to override onRetainCustomNonConfigurationInstance, and I ran into the following error, indicating FragmentActivity didn't have that method:

The method onRetainCustomNonConfigurationInstance() of type ... must override or implement a supertype method


here's how to fix it:

  1. open the android SDK manager


  2. update the compatibility package


  3. copy the updated compatibility package to the /libs folder of your project. see here for where to find the compatibility package: http://developer.android.com/sdk/compatibility-library.html#SettingUp




that last part's what got me; I assumed updating the compatibility package would update it in my project :P

Friday, February 10, 2012

Free resources for learning Python

I've blogged on here a bit about Python, but it occurred to me that I haven't actually provided any resources for anyone interested in learning Python.

A great place to start is learnpython.org. It's got simple tutorials as well as an interactive shell so you can try it out as you learn.

There's also Dive Into Python, a free book that's also been published by Apress.

Dive Into Python covers Python 2, but there's a Python 3 version available as well for free, published by Apress as well.

Of course there are a lot of other free resources available, but less is more, and these two are a great place to start. A more comprehensive list of resources, free and non-free, are available here: http://wiki.python.org/moin/PythonBooks

Have fun!

Friday, January 27, 2012

offline android development

if you ever find yourself with time on your hands and no internet (maybe waiting at the airport and like me, too cheap to pay $5 for a measly couple hours of internet), have no fear, you can still do android development. but you'll have to plan ahead, and set up a few things while you do have internet:

  • git
    so we all know git is a great, super-fast way to keep track of revisions in a decentralized way. because it's decentralized, you can commit changes to a git repository without any internet access. just make commits as you normally would, and then the next time you have internet you can push them to a remote repository like github.
    if you won't have internet access on your development machine, you can still update a remote repository by using a flash or other external drive:


    1. plug in your flash drive, and change to a directory where you wish to store a clone of your git repository:
      cd /media/my-flash-drive/some-folder


    2. clone your repository onto the flash drive:
      git clone git://example.com/myrepo.git


    3. now that you've got a clone of the repository, next time you're developing offline, you can pull local changes into the clone of the repository on your flash drive, like so:
      cd /media/my-flash-drive/some-folder
      git pull /home/myuser/path/to/repo


      if it gives you an error about specifying a branch, try tagging "master" to the end of the command, like so:
      git pull /home/myuser/path/to/repo master



    4. then, next time you're online, plug your flash drive in, and push the repo to your remote repository:
      cd /media/my-flash-drive/some-folder
      git push -u origin master


    I've got some basic git documentation on my wiki, but github's got better documentation on their help site.


  • android developer documentation
    unless you've got the android developer documentation memorized, you might find it handy to be able to access it offline. this one's really easy if you've followed their instructions on setting up the android SDK:


    1. open the android SDK manager using the instructions here: http://developer.android.com/sdk/adding-components.html#launching


    2. expand the latest version of the android API, underneath it check the Documentation for Android SDK, click Install, and follow the instructions.


    3. when it's finished installing, using a web browser navigate to the docs folder in the folder you installed the SDK, and open offline.html. the cool thing is that search works, even offline!









of course you'll need to have the SDK installed as well, but I don't mention that here because you kinda need to have that installed anyway.


have fun!

Monday, January 9, 2012

Using LIMIT with android ContentProvider

So you're using a content provider in your android app, and you want to supply a LIMIT parameter. The problem is, ContentProvider's query method doesn't have a limit parameter. Well, fortunately there's an easy solution; put the limit into a query parameter:
  1. First, in your content provider, create a constant for the query parameter key:
    public class MyProvider extends ContentProvider {
        public static final String QUERY_PARAMETER_LIMIT = "limit";

  2. In the query method of your content provider, get the limit from the Uri:
    public Cursor query(...
        String limit = uri.getQueryParameter(QUERY_PARAMETER_LIMIT);

  3. Still in the query method of your content provider, you can pass the limit on when creating the cursor:
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder, limit);

  4. Lastly, when calling your content provider (via getContentResolver.query(), a CursorLoader, etc), you can append the limit to the content uri like so:
    String someLimit = "15";
    cursor = getContentResolver().query(
        // add the limit to the content uri
        MyProvider.CONTENT_URI.buildUpon().appendQueryParameter(
            MyProvider.QUERY_PARAMETER_LIMIT,
            someLimit).build(),
            ...
The cool thing is you can use this same technique to pass other parameters to your query, like DISTINCT, for instance.

Monday, July 18, 2011

Python mysqldb UnicodeDecodeError: 'ascii' codec can't decode byte

Solution:

If you run into the error mentioned in the title of this post using python's mysqldb module version 1.2.1 or less, decode your data/query first:

mydata.decode('utf8')

(modifying 'utf8' to whatever encoding your data happens to be in)

Details:

So I was writing some code in python on Ubuntu, and it was working just fine. When I went to run it in RHEL, I got this error:

Traceback (most recent call last):
File "", line 50, in ?
File "/usr/lib64/python2.4/site-packages/MySQLdb/cursors.py", line 146, in execute
query = query.encode(charset)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 223: ordinal not in range(128)


My first thought was that it was due to the incredibly old version of Python that ships with RHEL 5 (Python 2.4), but it didn't take me long to realize the problem was with the MySQLdb module itself. Ubuntu 10.10 ships with version 1.2.2 of that module, while RHEL 5 ships with version 1.2.1. A minor difference, but apparently in that time this bug was fixed:
http://sourceforge.net/tracker/index.php?func=detail&aid=1521274&group_id=22307&atid=374932

Apparently MySQLdb 1.2.1 tries to indiscriminately encode the data to be put into the database to utf8 (well, at least when you specify utf8 as the database character set), without checking whether the string is already utf8 or not. My solution was just to decode my data from utf8 (to unicode) before passing it to my mysql query, at which point the encoding works just fine.

Like so (the first line's the relevant one):

mydata.decode('utf8')
query = ('INSERT INTO %(database)s (%(column)s) VALUES (%(value)s)' % {'database': database, 'column': column, 'value': mydata})
cursor.execute(query)


Of course, you should modify the 'utf8' part to whatever encoding your data is in.

Edit: If you're using MySQLdb.escape_string(), make sure you run that first before doing the decode, like so:

MySQLdb.escape_string(mydata).decode('utf8')

Friday, June 3, 2011

R.java: No such file or directory


solution:




  1. run this in a terminal:
    rm ~/.android/debug.keystore


  2. rebuild your project: go to Project --> Clean --> Clean projects selected below --> check your project --> OK







backstory:



okay, so I was tinkering with android today in Eclipse, and all of a sudden, my android project shows it has an error. not on any particular file, but on the project itself. normally when I get random errors, I select the project and go to Project --> Clean. today, that didn't work.

I wasn't seeing anything helpful in the console. after cleaning the project, I saw this in the console:

[2011-06-03 15:21:52 - android_test] ERROR: Unable to open class file /home/user/workspace/android_test/gen/us/test/test/R.java: No such file or directory

that was weird, because the file existed. so I went ahead and deleted the gen folder and rebuilt the project (which is what the clean command basically does), and still got the same error.

thinking my eclipse installation was corrupted, but too lazy to reinstall, I restored backups of various folders. no dice. I reinstalled the android SDK tools. nope. I checked permissions, tried reimporting my project, even tried creating a new project, and nothing worked.

finally, out of desperation, I deleted the .android folder in my home directory. success! after looking further into the issue, I found the solution here:

http://stackoverflow.com/q/2194808/399105

although what frustrates me the most is I never saw any errors related to the debug certificate.

of course, wanting to know the details, I ran the keytool command on my backup of the old keystore (the keystore password is "android"):

keytool -list -keystore ~/Desktop/android-backup/debug.keystore -v
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: androiddebugkey
Creation date: Jun 3, 2010
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Android Debug, O=Android, C=US
Issuer: CN=Android Debug, O=Android, C=US
Serial number: 4c07f835
Valid from: Thu Jun 03 13:45:09 CDT 2010 until: Fri Jun 03 13:45:09 CDT 2011
Certificate fingerprints:
MD5: 49:56:C0:A8:02:9F:38:97:81:D1:22:BA:F3:50:17:23
SHA1: 3D:E8:57:A1:87:97:45:EA:AD:E2:03:66:29:3A:36:DE:9F:F5:35:43
Signature algorithm name: SHA1withRSA
Version: 3


...and there's my exact problem: it looks like the debug certificate generated by the Android SDK is only good for a year.

oh well, at least I'm back in business :)

Edit:

argh, I just ran into this again, but it took me a while to find it because this time the error was "Your project contains error(s), please fix them before running your application." selecting the project, then going to Window --> Show View --> Problems gave me the error "R cannot be resolved to a variable". gotta love these detailed errors...

well I shouldn't run into this again because Google's changed it so now my debug certificate is good for 30 years :)

Wednesday, June 1, 2011

nullege.com: search python source code

the title sums it up pretty well. I know you can find just about anything using google, but supposedly nullege.com is a little smarter when it comes to python. it's a cool idea, at any rate. I haven't had a need to try it out yet, but I'm sure I will before long:


http://nullege.com/

Wednesday, March 9, 2011

python's only problem: concurrency

python has its naysayers, but that's what jealousy will do to you :) seriously though, python does have one major issue: concurrent/parallel programming. now I'm no engineer, and I'm sure this is an oversimplification, but three ways of accomplishing this are:


  1. using multiple threads

  2. using multiple processes

  3. event-based programming



the main killer out of these three is trying to do multi-threaded programming in python. the short answer: don't. when Python was designed, it was given the philosophy that people using it should have to worry about as little as possible under the hood. while that's great, the way the python threading library was designed makes it inefficient for CPU-bound tasks. essentially, the more threads you use in python for CPU-bound tasks, the slower your code will be. ironically the problem seems to be even worse on machines with multiple processors. the problem has a name: the Global Interpreter Lock (GIL). you can read more about it here:

http://wiki.python.org/moin/GlobalInterpreterLock

there's also a great presentation that explains the problem pretty well if you have time to watch it. I'll put it at the bottom of this post.

then there's the issue of event-based programming. the problem in this arena (in my opinion, of course) is that there are too many choices for event-based programming, and none of them are included in the python standard library, so there's no standard as of yet.

lastly there's multi-process programming, which thankfully is in a better place than the other two. although it's only been fairly recently (within the last couple of years), python now has a multiprocessing module in the standard library. so if you're looking to write some concurrent/parallel code, I'd say start with here before wading through the alternatives that aren't in the standard library:

http://docs.python.org/library/multiprocessing.html

as the speed of computing becomes increasingly more about multiple processors than faster clock speed, the more important this issue will be. thankfully there's a standard solution (the multiprocessing module) as well as plenty of alternatives, and hopefully in the near future one or two of these alternatives will become standard, if not at least de facto.

here's a page that has links to some resources related to concurrency in python, as well as links to plenty of the afore-mentioned alternatives:

http://wiki.python.org/moin/Concurrency

and here's that video I promised:
[blip.tv ?posts_id=2243379&dest=-1]

Tuesday, March 8, 2011

Python and MySQL autocommit

Solution:

If your MySQL database is using the InnoDB engine, commit your changes after database transactions:
cursor.connection.commit()

Or just turn on autocommit to automatically commit after every database transaction:
cursor.connection.autocommit(True)

Details:

So I was using python's MySQLdb module to edit a mysql database, and I noticed that even though python was telling me my modifications were taking place, I wasn't seeing any changes. in addition, when I would log onto the database from something other than python and try to make changes, I would get this error:

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

Well apparently, the mysqldb module now disables mysql autocommit by default. so now, when I'm done with my transactions to the database, I need to commit my changes by calling the commit() function of the connection object. the connection object is what's returned when you call the MySQLdb.connect() function. I haven't really been using that object in my code other than to create the cursor object, which is what I normally use:

db = MySQLdb.connect(...)
cursor = db.cursor()


But the cursor can access the connection object, which I can then use to commit the changes:

cursor.connection.commit()

The strange thing with all of this is that I just started noticing this problem, even though according to the MySQLdb module authors, this functionality (disabling autocommit by default) has been in place since version 1.2.0 of the module. but when I look at the package versions of python-mysqldb for Ubuntu (what I'm currently using and have been for a while), it looks like it's been past version 1.2.0 for the last several years:
http://packages.ubuntu.com/search?keywords=python-mysqldb&searchon=names&suite=all&section=all

Maybe this "feature" has just recently made it into Ubuntu's package for this module. or maybe I'm missing something else here. at any rate, at least I know what's going on.

You can see here for more information:
http://mysql-python.sourceforge.net/FAQ.html#my-data-disappeared-or-won-t-go-away

Edit:
Okay, so apparently what happened is in my other code where I was modifying mysql databases, they used the default engine (MyISAM). the database I was having problems with was using the InnoDB engine, which is a transactional storage engine. this explains why I just now saw this issue.

More information here:
http://stackoverflow.com/questions/1617637/pythons-mysqldb-not-getting-updated-row

As well as an alternate solution: instead of committing after every transaction, I can turn autocommit on when I'm working with databases using the InnoDB engine, so they'll function just like the rest:

cursor.connection.autocommit(True)

Monday, February 28, 2011

Vala, Vala everywhere!

...okay, okay, maybe not everywhere. But since I posted on Vala a while back, I've noticed a couple of teams in particular seem to have embraced it wholeheartedly. What's really cool is that these teams have been writing some really impressive software for GNU/Linux in Vala. Nearly all of these software projects were started within the last year or two, and these aren't your grandma's Linux apps. These are sleek, fast, and have a strong focus on usability and a nice, clean interface. They're really worth checking out.

Here are the teams and their software:
  • Yorba
    • Shotwell (photo organizer)
      This one's extra impressive because in less than two years it's gone from brand new project to the default photo manager for top GNU/Linux distributions Ubuntu and Fedora
    • Lombard (video editor)
    • Fillmore (music recorder)

  • Elementary
    These guys started out creating slick themes for Ubuntu, and before long started making their own apps. They've started up so many software projects, particularly in the last year, I don't know how they could possibly have time to work on them all:
Elementary has another app named Dexter, an address book, and although it's currently written in Python, I wouldn't be surprised to see it go the way of some of their other apps like Purple.

There's also Midori, a lightweight browser, which I don't think the Elementary team started, but I know they contribute to it, and somehow or another Vala is involved, possibly due to their influence.

As if that wasn't enough, next month the Elementary team is releasing their own GNU/Linux distro, based on Ubuntu, but with a cleaner interface and packaged with many of their apps. Here's an early screenshot:

Thursday, February 17, 2011

Wednesday, October 27, 2010

Why Python?

It's occurred to me I haven't posted much on Python, which has been my preferred computer language for the last couple of years. Nothing else compares: it's high-level, object-oriented, actually encourages easily-readable code, and doesn't get in my way as a programmer.

Granted, I'm not an expert in the field, but every time I have to program in other high-level languages such as PHP, Java, bash, or (in a worst-case scenario) Perl, I realize how much Python has spoiled me.

Here's a link to an amazing article that got me to consider Python (and I would imagine it's probably done the same for many others):

http://www.linuxjournal.com/article/3882

Enjoy!

Thursday, July 15, 2010

Genie/Vala

You wouldn't know this from reading my blog, but I'm a Python fanboy. Maybe I haven't blogged anything about Python because it's already so completely awesome that there isn't much to blog about. Well, anyway, today I stumbled upon an interesting programming language called Genie:

http://live.gnome.org/Genie
http://en.wikipedia.org/wiki/Genie_%28programming_language%29

Genie is pretty intriguing for many reasons. It's a high-level language that uses the Vala compiler. What is Vala?, you might ask. Vala is a high-level language that can be used to write cross-platform code. It's syntax is similar to C#, but unlike C#, Python, Java, or many other modern high-level languages, it doesn't need a runtime environment/VM to run, because it compiles to C, which then of course compiles to machine code. And because it compiles to C, it can be used to write cross-platform applications, on anything that supports GLib, which at the very least covers the big 3 (Windows, OS X, GNU/Linux).

So Vala itself is pretty cool. What makes Genie even cooler is that it has more of a Python-like syntax, which, of course, is one of the coolest things about Python (for those of us that happen to like Python). And Genie and Vala can be used alongside each other.

How's this for a Hello World?:

init
print "Hello, world!"


Granted, not quite as basic as a Python Hello World:

print "Hello, world!"


but basic enough. It's sure nice on the eyes without all those curly braces and semicolons at any rate.

So... if at any point I am developing an application and want the benefits of a compiled language that doesn't rely on a VM, I'll definitely be checking out Genie. And for those of you who aren't too fond of Genie's syntactical style, I'd recommend checking out Vala.

If nothing else, it sure beats trudging through C/C++. Yeah, they're not bad languages, but it seems to me with the way technology is continually advancing, it's ridiculous that C/C++ are still sometimes the best options for software development, especially when it comes to performance. Who knows, maybe Genie/Vala are the next C++. Then again, maybe not, but they're definitely worth looking into.