‏إظهار الرسائل ذات التسميات english-posts. إظهار كافة الرسائل
‏إظهار الرسائل ذات التسميات english-posts. إظهار كافة الرسائل

الخميس، 30 مايو 2013

A Prolog for my Kalimat

I've tried twice to add program analysis to Kalimat, and each time I had trouble. Program analysis is collecting data about the program to use for IDE features like 'go to definition', autocomplete, 'find usages', and so on.

Basically this operation has 3 parts:
  • Regularly parse the code in the editor windows (for speed most IDEs reparse only the changed parts of the code).
  • Update a program database that holds information like what methods are defined in each class, where is some variable declared,...etc
  • When you need to do some action like 'go to definition', query that database
Let's ignore part #1 and focus on updating and querying the program database. The first time I implemented it the solution was very ad-hoc: I stored things in hashtables, queried them with loops, and the code was very tedious, repetitive, and error-prone.

This was clearly not good, so I decided to use a real database: SQLite is a lightweight database engine that can be easily embedded in other programs, and also has the option to store data in memory instead of on disk. Perfect. In the second iteration the code for 'go to definition' looked something like this:

QSqlQuery q;
q = progdb.q("SELECT defining_token_pos, function_definitions.module_filename "
   "FROM function_definitions JOIN definitions ON definitions.id=function_definitions.def_id AND "
   "definitions.module_filename = function_definitions.module_filename WHERE (definitions.module_filename IN (SELECT imported FROM "
   "module_imports WHERE importer=?) OR definitions.module_filename=?) AND definitions.name in (SELECT lexeme FROM tokens WHERE pos <=? "
   "AND pos + length >=?)", filename, cursorPos, cursorPos, filename);
if(q.next()) { 
   docContainer->OpenOrSwitch(q.value(1).toString());
   ((MyEdit *)currentEditor())->;jumpToPos(q.value(0).toInt()); return;
}

It might look complex but the idea is simple, what the query's trying to say is "Find the filename and position of the function definition that has the same name as the name under the cursor. When looking for a function definition, look in the current module or any module imported by the current module".

This works, but has a lot of drawbacks

1- The query isn't recursive. If the current file imports module A, the IDE will look there for definitions, but if we import 'A', and 'A' imports 'B', the IDE will not look there. We want all modules reachable from the current module to be found.

SQL isn't very friendly with recursion so I probably would've had to implement recursion myself with C++ code.

2- The bigger problem is that the SQL here is too complex. Sure it beats loops and hashtables but it's still big, and that's only for 'go to definition'! How about when I add public and private definitions? namespaces?

What I need is a reasoning system. Luckily there's one: Prolog.

Actually I don't need the full Prolog language; a subset of Prolog has been created to support complex queries (much more complex than SQL), this subset is called Datalog, and it's successfully used in program analysis in many research projects.

I set out to find a nice Datalog implementation for my aims, but didn't find something sufficient: there's an excellent library called BDDBDDB but it's in Java, and there's another one called simply 'Datalog' written in C and Lua that seemed not straightforward to integrate with Kalimat (nb: Kalimat is written in C++/Qt).

Then I looked at open source Prolog implementations like SWI or Ciao, and while very powerful and fast, they didn't seem easy to integrate with a standalone C++ app, especially an app like Kalimat that has to run on both Windows and Linux. I might be wrong but I felt it wasn't easy.

So what did I do? Why, created a new Prolog implementation of course! It's called SmallProlog (and nicknamed 小さい Prolog), specially designed for integration with C++/Qt.

Using Prolog from C++ has never been easier:

PrologEngine engine;
engine.load(prologCode);
engine.call("predicate", arg1, arg2, [](QMap<QString, QVariant> sol){ 
 // do stuff with each solution
});

The expression [ ](QMap<QString,QVariant> sol){ ... } is a lambda expression, a new feature of C++. You define here an anonymous function that gets called whenever the Prolog engine finds a solution. The 'solution' will be a map from variable names to their values.

Under the hood the engine stores facts in a SQLite database, but this time the queries are generated for us from a higher level and more expressive language.

So how does 'go to definition' look now?

usagesOfProc(DefModule,DefPos,UseModule,UsePos):-
   
visibleFrom(UseModule,DefModule),
    procInvokation(UseModule,Name,UsePos),
    proc(DefModule,Name,DefPos,_,_,_)
    .
  
visibleFrom(Mod1, Mod2):-
    visibleFrom2(Mod1,Mod2,[Mod1]).
visibleFrom2(M1,M1,_).
visibleFrom2(M1,M2,Visited):-
    imports(M1,Temp),
    not(member(Temp,Visited)),
    visibleFrom2(Temp, M2,[Temp|Visited]).

The second predicate, called visibleFrom, can take a Kalimat module and give us all the other modules reachable (recursively) from the first module, including itself.

It can also work in the opposite direction: given a module it can give us all modules that 'see' it. The power & elegance of Prolog at work.

The first predicate, called usagesOfProc, takes a module & a position of a function call, and gives us another module and position where the function is defined.

It can also work in the opposite direction: given a function definition, it can give us all files and positions where the function is called.

So when I implemented 'go to definition' I was also implementing 'find usages'; write a feature and get one for free! The power & elegance of Prolog at work.

Aside: I wish the makers of Prolog implementations marketed them as languages for more than industrial and vertical market type applications, and made them trivial to integrate with all types of other languages.

Also, to help myself with debugging, I made a Prolog console where I can query the Kalimat program database live, while the IDE is running:



It's an experiment, and it's still unfinished so I don't know if it'll work as I desire or not, but I'm very excited about it. Aren't you? :)

الاثنين، 11 مارس 2013

Kalimat: an educational programming language with a twist

I've been working on a language for teaching programming to children. One sentence summary: It looks like the child of QBasic and Google's Go, with influences from other languages.



The  syntax and programming environment are geared towards educational use, but the VM on which programs run (called SmallVM) has support for microthreads, CSP channels, and an FFI. The language itself has things like lambda expressions, a limited form of destructuring, and opt-in tail call elimination.

This article will be divided into two main parts, the first of which discusses Kalimat as an educational language for beginners, and the second shows some of its more advanced features, talks about the implementation, and mentions some ideas about taking the language forwards.

A little background

Kalimat started as an Arabic-based programming language, but I've decided to turn it into a bilingual one; with a compiler switch you can have Arabic or English-based syntax with a corresponding IDE and standard library. I'm doing what I can to make both languages equal citizens, but Arabic still has a higher precedence since the goal of Kalimat is to help the Arab-speaking world learn programming, and to provide a means of "computational empowerment" to non-programmers.

Kalimat was made bilingual because:
  • Often, the novelty of an Arabic-based language dominated the conversation when I wanted to talk about the design and features of the language itself. Having an English version would make it simpler to talk about the technical details.
  • I wanted to interact more with the global PL community, the majority of which are English speakers.
  • To help with scientific studies about teaching programming with PLs in native vs. non-native human language.
  • As a bonus, working with an English version of Kalimat showed me some verbosity in the original syntax which I hadn't noticed since I was too used to the original syntax I had designed.

The language can be downloaded from here, with pre-built English and Arabic versions for Windows. Non-Windows users can check out the source and build it with Qt Creator and the Qt library (version 4.8.x), but they would need to uncomment the following line in both of the files 'kalimat.pro' and 'smallvm.pro' to Enable English syntax/IDE:

#DEFINES+= ENGLISH_PL

Moving on....

Basic syntax

This is a word-count sample in Kalimat:

read "Enter some text:", str 
words = split (str, " ")
result = {}
for word in words:
    if not containsKey (result, word):
        result[word]= 1 
    else:
        result[word]= result[word]+ 1 
    done 
loop 

for pair in result:
    print key pair, " : ", value pair 
loop 

Looks kind of Pythonic, and the code is self-explanatory I think! We have the basics: Simple input and output, iteration, dictionaries (arrays are also supprted), and conditionals.

Here is another quick example:

proc lines (a):
    for i = 1 to a :
        drawLine(random (800), random(600))-(random(800), random(600)), random (16)
        wait (100)
    loop 
end 

lines (200)

In Kalimat a user can define a proc or a func, with the latter being able to return values to the caller (similar to the Sub/Function dichotomy in Microsoft's *-Basic languages). In my opinion this makes the language easier to teach since we can explain procs as 'pieces of code with a name', and worry later about passing parameters and using return values. Experimentation would tell if this was the right decision.

As seen from the drawLine statement, Kalimat has graphics commands that were taken as they are from 80s BASIC, we also have drawPixel, drawCircle, drawRect, drawImage and drawSprite.

We have classes and objects in Kalimat too:

class Point :
    has x, y 
    responds to draw ()
end 

response Point p to draw ():
    drawPixel (x p, y p)
end 

p = new Point having x = 120, y = 150 
p : draw ()

Like the proc/function division, an object can respond to a message sent to it, or it can reply with a value.

The syntax is a little verbose but I have a hypothesis that it would pay off when teaching OOP to beginners. In my brief period of teaching OOP (to college students) I have often found that the syntax of a language like C++ has too many implicit meanings (what 'this' means, what happens in a line like a.b(c)...etc) and that when the students see this syntax they need constant reminding of what it actually represents.

I've tried to make the stuff that happen behind the scene explicit in the syntax, things like 'I'm sending a request to the object, the object shall respond, the response has a reference to the actual object...). When they have fully grasped the semantics the learners can move on to more mainstream languages (or an additional, more streamlined syntax, could be added to Kalimat).

Combining graphics, OOP and Kalimat's sprite engine; we can remake the QBasic classic Gorilla example. The code for that example (and others) is bundled with Kalimat's distribution, or it can be seen here.

Finally, Kalimat has features to help specifically with teaching:
  • The 'Edit' menu has a 'Copy as HTML' feature to help post code in online tutorials and the like. The examples in this blog have been formatted that way (but some minor annoyances in spacing had to be manually corrected; I hope I can fix those annoyances soon).
  • The 'Program' menu has a feature called the monitor which provides an animated trace of a program, while showing the call stack in the 'Variables' tab at the bottom.
  • The 'Test' menu has the option of showing the SmallVM IL generated from source, which could be useful if someone wants to use Kalimat for teaching compilers. It's planned to later add features for visualizing basic blocks and control flow in methods, mainly to help me debug the VM; but could also be used in teaching compilers.
This concludes our brief tour of Kalimat as an educational language, now we move on to concurrency and other more advanced features.

Concurrent processes

Those five forms are the main ingedients for working with processes:

launch procInvokation ()
c = channel ()
send val to c 
receive var from c 
select :
 send 123 to c1 :
   -- statements
 or receive x from c2 :
   -- statements
done

Processes are scheduled internally by the VM and are independent from operating system processes or threads. The launch statement starts a process, the channel() function creates a new channel, send, receive and select statements enable communication between processes using channels as a data exchange/synchronization mechanism.

Both sending and receiving are synchronous (a sending operation blocks until another process is ready to receive from the channel and vice versa), and the select statement takes a set of alternative channel operations and applies the first operation that is ready to run, along with its associated sub-statements; if more than one operation were ready at the same time one operation is chosen randomly from among them.

(If you're familiar with Google Go, then all of this is old news to you).

Why were these features added? Again based on some hypothesis I have about teaching programming. The goals were:
  • To enable children to create games and animated scenes where multiple agents move and behave independently
  • To make GUI programming easier (all GUI widget events are represented by channels, you could model a sequence of GUI interactions with sequential statements: receive some event from channel1, then receive another from channel2...)
  • Since we seem to be entering an age of concurrent programming, it doesn't hurt to have a language where it's easier to teach the concepts of concurrency

I think it's interesting that channels support Kalimat's iteration protocol, so you can say

for someVar in myChannel:

..and have the system iteratively receive data from the channel until it's closed. This feature encompasses the capabilities of something like Python's generators (or yield return from C#) but I think it's more powerful than either of them; for example, from what I've seen it's somewhat cumbersome to use yield to recursively create an iterator for a tree in Python, however in Kalimat it's very natural:

for elem in enumerateTree (t):
    print elem 
loop 

proc enumerateTree (t):
    chan = channel ()
    launch traverseTree (t, chan)
    return chan 
end 

proc traverseTree (t, chan):
    traverse (left t)
    send data t to chan 
    traverse (right t)
end

What we did was a little bit of glue code, then a traditional tree traversal, sending whatever we visit to the channel.

Simple destructuring

We have syntax to test if some given data has a given structure and to extract data from that structure. In this example we'll be testing if a given value is an array, map, or object:

proc showName (x):
    if x ~ [?first, ?last]:
        print first, " ", last 
    else if x ~ {"firstName"=>?x, "lastName"=>?y}:
        print x, " ", y 
    else if x ~ Person having firstName = ?x, lastName = ?y :
        print x, " ", y 
    done 
end

Preceding a variable name by ? extracts the corresponding component into the variable, otherwise the component is tested for equality against the variable (using the same ?var twice destroys the first value, this feature is not really pattern matching/unification). Matching keys in a map cares only about the subset of keys being tested (i.e other key/value pairs could exist and the match would succeed), the same goes for testing fields in objects. Matching on arrays like this x ~ [a, b, c] tests against the exact array count, but x ~ [a, b, c, ...] can successfully match a larger array.

Tail call elimination

The statement delegate to someInvokation() can be used inside a procedure or a function in Kalimat to properly tail-call some routine. This feature was created in case an educator wanted to teach certain styles of programming, and to make the VM extensible (for example to make it possible to support continuations if so desired).

Parser generation

Kalimat has a built-in parser generation engine (this was made with the intention of using Kalimat to teach computer science and not just programming, and to enable the creation of natural language interfaces, text adventure games,...etc by kids).

For example writing this code

rules expression :
 
expression = term:a "+" expression:b => ["+", a, b]
or term:a "-" expression:b => ["-", a, b]
or term 

term = number:a => toNum (a)
or "(" expression:a ")" => a 

number = digit:a number : b => a + b 
or digit 

digit = from "0" to "9" 
 
end

...would provide a function called expression that takes a string and returns a parse tree for simple arithmetic expressions. The capability uses PEG notation with a memoizing packrat parser. Unfortunately the generated parsers can't currently handle left recursion (thus the above grammar actually has a subtle mistake because it treats subtraction as right-associative). I've read the various papers about handling left-recursion in PEG's, but I have yet to understand the techniques :)

A function-plotting sample application that demonstrates this feature is bundled with Kalimat, or could be seen here.

There are two interesting additions that could be made to the parsing engine:
1- Adding the ability to parse any enumerable stream of data, not just a string, and to pattern match against data. This would be like OMeta and its various derivatives.

2- Since channels are enumerable, this would make it possible to parse anything that could be sent to channels: imagine the ability to write grammars for GUI interaction models, sequences of packets from the network, routing web requests, and so on; basically enabling the creation of grammars for things for which we now create state machines.

If features #1 and #2 above were well-implemented I think it would give way to an exciting, highly declarative style of programming.

Implementation

Kalimat code runs on a custom-made VM called SmallVM. It's a simple stack-based machine that runs concurrent processes using an internal scheduler. It currently uses two threads: one for code execution and the other for GUI.

Because Qt does not allow GUI operations to run outside the event handling thread; the GUI thread also has an interpreter instance. A process that needs to do a UI operation migrates to the other interpreter, does its job, then migrate back to the main execution thread. There are plans to have multiple execution threads and to multiplex the execution of processes among them (like Erlang or Go).

An ambitious project would be to hook the VM scheduler to libuv and have the ability to schedule tasks Node.js style but without the callbacks, since the VM would suspend and resume processes automatically.

Performance wise, I could describe SmallVM as "somewhat satisfactory for its intended goals". On my machine, executing fib(30) takes about one second in Python but 3 seconds in Kalimat. On another dual core machine the time for Python is still one second, but for SmallVM it becomes about 1.4 seconds. I have yet to run more scientific benchmarks.

The VM has a simple FFI built using libffi; it supports calling C functions and having callbacks to Kalimat functions. The callback feature is currently still in development since it has a complicating issue: what happens if C code calls a Kalimat procedure, then that procedure waits on a channel until another process sends it something ?

To make the above case work invoking a callback has to run a secondary VM execution cycle, not just run the code of the callback procedure. Even running in multiple threads wouldn't completely solve the problem. The code to handle these cases is already in the VM, but not really tested and is expected to be buggy for now.

This applies to Kalimat in general: I think I might have some good ideas for designing a PL but I'm not so good at implementation. The language has its fair share of bugs and quirks, and now with the English based IDE the quirks have increased (expect to see the occasional untranslated error message or right-to-left dialog box for the time being). However I'm pushing on, and I hope the product keeps getting better over time.

Thanks for reading about my small programming language; I hope something from it got your interest!

الخميس، 8 نوفمبر 2012

A notation for a sketch-based programming language

This is my design for a language called "SketchCode". The language tries to enable sketch-based programming, both on a traditional paper pad or on a tablet-like device, and strives to maintain simplicity and clarity of the sketches by reusing whatever notations people already use when sketching and by introducing as few new notations as possible.

Instead of making the code itself graphical, the system keeps the code mostly text based while using graphical notation for data structures. Blocks of simple shapes indicate objects, arrows indicate object references, tables indicate records or arrays.

As you see, this simple scheme already allows us to represent many kinds of data. In SketchCode our program should be mostly graphs, state machines, ...etc, I like the idea that a program's data stands out more than its code.  As Fred Brooks said: Show me your flowchart and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won't usually need your flowchart; it'll be obvious

The graphical nature of the data allows us to program by pattern matching as seen in a lot of functional languages. An important set of new notations would be the language of pattern matching: how to indicate matching a variable? How to match a part of an array or structure?



The first example shows how to calculate the sum the elements in a (sketched) linked list, the second shows how to extract data from a record, and the third shows the notation for 'if' statements.

Tentatively, I chose to underline an identifier in a pattern to indicate being a variable, and the "piece of a table" to indicate partial record matching. It would be interesting to see how to indicate other notations like a part of a graph or a slice of an array.

I have also borrowed some notations from math, and an implemented system could add traditional notations for things like roots, fractions, summation,...etc

A lot can be done with just those basic components: we could have unit tests with sketches of test input, or a "console" where we sketch function application to evaluate it, and more. From there, there is so much that could be added.

Of course, such a system needs to be implemented in order to find out whether this design is really sufficient to express interesting programs, and whether such expressions are actually natural to draw/understand, and how to e.g naturally modify an existing program.

الخميس، 26 أبريل 2012

An educational tower of programming features

I've been working on an educational programming language for children called Kalimat. One of the ideas about its design is "different concepts for different levels".

Some languages are quite easy to learn, like 80s Basic, while others try to still be easy but add structure or discipline. There's this famous Dijkstra quote (probably made in jest) about Basic ruining children's minds beyond all repair.

Well, Kalimat goes the other way by assuming "all repair" is possible, even a good thing: it starts with a language very similar to QBasic; a child can write interesting programs using only global variables, If conditions, and goto. They can learn with flowcharts if it benefits them, and they can use graphics routines.

We can call this "Level 1". Gradually, these primitive features are shed in favor of more advanced, more abstract features.

Kalimat is Arabic-based, but I'll use a hypothetical English version for the example. This is the typical 'guess the number' game:

n = random(20)
label begin
read "Guess the number:", #g
if g > n :
    print "too high!"
    goto begin
else if g < n :
    print "too low!"
    goto begin
else
    print "good job!"
done

The benefit of this model is that almost everything is visible. The child doesn't need to know the abstractions of procedure calls, or keep in their head the semantics of such calls when thinking about what to do. Commands are executed, sometimes execution jumps. Variables store numbers and sentences, and that's more or less it. Now let's move stuff on the screen or write short quiz programs.

If the child outgrows the kind of programs this model allows, they can learn looping with for and while, and further learn procedure calls. Procedures are separate from functions: this allows the teacher to talks about procedures as "taking some lines of code and giving them a name", and then enter the realm of local variables and parameter passing, and finally talk about "defining our own functions" similar to built-in functions like sin, cos, or random. Let's call that level 2.

Level 3 is OOP. While OOP is now all about abstraction, there's some bit of "concreteness" left: There is no implicit "this" or "self" reference, and like, say, Python this reference is explicit. We also borrow the "send a message" metaphor from Smalltalk. An object can respond to a message or reply to it. Mirroring procedures and functions (I admit this part looks clumsy, needs experimentation to see if it turns to actually make the teaching easier).


class Point:
    has x, y
    responds to draw( )
end

responseOf Point p to draw( ):
    drawPixel (x of p, y of p)
end 

You've probably noticed the usage of cues from natural language to make reading programs flow more naturally. We are not trying to emulate COBOL or SQL; but we believe such cues in the right dosage could help with teaching and conversations about the code. I intend for Kalimat to have something of a canonical reading form, that is when reading code aloud, there is a known way to voice expressions, definitions, ...etc

Anyway, I like the result in the code snippet:  "the response of a point P to 'draw!' is to invoke drawPixel at the x and y of P".

How about other levels? Now that the child's programming knowledge has matured, they can learn more: like for example concurrency. Kalimat uses the CSP model. First we have the launch command that takes a procedure invocation and runs it separately. It's easy to take a program that draws an animated ball and transform it into 50 concurrently moving balls, with the simple addition of a loop and a launch statement.

To coordinate between processes, we have channels and their usual operations: send, receive, and select. Those same channels are also used for the GUI library; in my opinion this simplifies GUI programming in many situations. For example to create a program where the user draws lines you could do:

while true:
    receive p1 from mouseClickChannel( )
    receive p2 from mouseClickChannel( )
    drawLine (x of p1, y of p1)-(x of p2, y of p2)
loop

The flow of execution matches the flow of user actions, no need to separate program state, and in larger programs the need for some design patterns is minimized.

Other than concurrency, Kalimat has (explicit) tail-call elimination for any ambitious teacher who wants to go into functional directions, and currently I'm working an a language-hosted PEG parsing, for people who want the children to create e.g NLP user interfaces, text-adventure games, or whatever they fancy. Kalimat is all about teaching thinking, computer science, and the fun of programming.

I did the design of Kalimat on intuition and from memories from my childhood days of programming, but I've recently found out about Piaget's well-know theory of child intellectual development stages. I'm not so sure about this, since I'm far from being a development psychologist, but there might be some fit between Kalimat's primary, abstraction-free, levels and the operational model of early childhood learning. This might be able to explain the exploding success of 80s Basic among children and allow us to take advantage of some of its characteristics.

Kalimat is open source, hosted on http://code.google.com/p/kalimat

It is Arabic-based, but I hope to have an English version for better discussion and experimentation with the global programming education community, if anyone turns to be interested.

I once made a buggy, half complete English release (here's a screenshot of it). I don't want to publicly release it at this stage, but I'd be happy to give it to anyone who requests. My email ID is samy2004 on Gmail.

الاثنين، 9 أبريل 2012

Where is the casual programming?

I did not learn to program to have a software development job. True story.

I learned it for two reasons: (1) To have an aid for thinking and expressing ideas. What Steve Jobs called "A bicycle for the mind". (2) To automate repetitive tasks. Unfortunately, I don't seem to be doing much of either.

Perhaps some people are doing more than me. The Unix/Linux fans - some of them - write adhoc shell scripts or one-liners to solve casual problems. Perl and Python were created for such tasks. I suppose I could be complaining of a non-problem, except it is a problem. Programming is not casual enough.

The first barrier to casual programming is that you've got to learn too much stuff (too much to call it casual). This is the first and only shell script I wrote:

#!/bin/bash
cp -R Program ProgramCopy
cd ProgramCopy
find . -name bin -exec rm -rf '{}' \;
find . -name obj -exec rm -rf '{}' \;
zip -r ../Program`date +%d%B%y`.zip * -x \*~
cd ..
rm -rf ProgramCopy

It takes a program directory, removes temporary compiler generated files, and puts the code in a zip file with today's date. I made it with by trial, error, and Googling. It made me not want to write shell scripts again; feels too much like piecing together jigsaw puzzles where you first have to know which pieces actually exist.

Would I read a book about shell scripting? Nope. It's too much of a hassle for solving only one bit of the casual programming problem. Wouldn't help me much with writing a quick GUI or Web app to solve the problem, or to pull some data from Excel and write them into a .pdf

So how about Python? It has lots of libraries to do all of that and more. The problem is twofold:
1- The user needs to find the required libraries.
2- The user needs to read the documentation of those libraries.
3- The user usually does this with little less than an editor and an open browser tab.

That's the real problem with dynamic typing: With Java, C# and C++ I learn APIs on the go. I use autocomplete and when in doubt I point to the function invocation and press F1 to read the manual entry about this function. If I feel I need more background information, I follow the links higher in the doc hierarchy and begin learning about the big picture the exact moment I realize I need to learn this stuff.

I always wonder how Lisp and Python fans go along. They actually remember the difference between mapcar, mapcan, mapc...maybe I'm stupid or something.

But with the big three static languages, I have another problem: The IDEs take toooo long to load. If I need to write a utility to rename files in a certain way; I don't think "sure, I'll fire Eclipse, create a new Java project in the workspace, create a new run entry, & write and test the code".

Visual Studio? Qt Creator? the same.

What else? I wish everything had an easy to access API. If I can do it as a user, I want my code to do it. You know those cool hacks where people program small robot cars to bring them coffee? They should be trivial to write. I want to write a utility to, say, extract my old blog posts and find all posts written in Arabic, and tag them with "arabic-posts", and I want it running in a time comparable to what it took to describe it.

func isArabic(str)
...
end
blogger.blog("iamsamy", pw="*****").posts.contents.filter(isArabic).tag("arabic-posts")


You know what? Maybe there's a library that actually does this; but I need to find a "gem" or "egg" or "crate" or whatever to do it. And I need to read the docs. And the library may be out of date. And I'd be writing this in a command line window or an editor without autocomplete. And when I have a different casual, trivial, task, I'll need to do so all again.

Oh man. And I'm a professional and experienced programmer. How about the grocer or pharmacist or school student? We need things to be better!

Ok, we can start with a decent language with excellent library support (or we can develop a new one if we feel we have too much time on our hands). Maybe Rebol or Python or Ruby; they seem to be created by people who like to write code for solving casual problems.

If the language is dynamically typed, we could use some sort of technique to enable auto complete, like type inference or such. Otherwise use a fun but statically typed language, maybe C#.

Now we need an IDE that
  • Loads fast
  • Has very tight integration with a library repository, with a catalog of only the best libraries, easily searchable. I should type "blogger", find at most one or two working options, and press "add". I should be able to see the documentation before pressing add.
  • The documentation should have working examples for the top 10 casual tasks usually done with this library. If I'm lucky I'd press "copy this example", "run", and be done.
  • The IDE should have little cues in the code, like allowing me to select a directory from a dialog then use it as a file name in the File object's constructor, or choose a URL from my current browser tabs...etc
  • There should also be some form of API discoverability. I should search for "convert jpg" and find a class to do the task, even if the name doesn't neccessarily include "convert" or "jpg".
  • There should be a trivial to use GUI kit - like say Shoes - and a similar web kit.
I could go on and on....

الجمعة، 9 مارس 2012

All about pointers: part 2

So now you learned pointers from part 1, right? What can we now do with them?

Well, we can use pointers in two ways:
1- As an abstraction over variables.
2- As just a memory location.

Abstraction over variables

Normal variables let us abstract over values; meaning "do something with x whatever value it has". Well, pointers let us store variables in variables, so to speak, and thus abstract over them.

For example, there is no pass by reference in C, but we can emulate it with pointers:

void readInt(int *x) {
cin >> *x;
}
main() {
int t;
readInt(&t);
}

The function main is passing the location &t (by value) to readInt. When readInt modifies *x, this means "go to the address stored in x, and in that address, store whatever comes from cin >>". This modifies the value of t; which is what we wanted.

This pass-by-value works for anything that has a memory location; not just simple variables:

main() {
Point p;
readInt(&(p.x));
}

This will take the address where p.x is stored, and pass it to readInt; so it will be the address where readInt will write.

Is there another use of 'abstraction over variables' other than pass by reference? Well, this depends on your imagination. We can do things like this:

void getAge( ) {
int x = 8;
dialog.scrollBox1.setBinding(&x);
showDialog( );
cout << x;
}

Here we can imagine the setBinding function storing a pointer to an integer (pointing to x in the example) and whenever the user slides the scroll bar, the content of the address stored in the pointer is changed. Therefore after the showDialog function ends we find the value of x automatically reflecting the scroll bar position. It is as if we passed the variable itself as an argument to the setBinding function.

Pointers as memory locations

We can also treat a pointer as just a location in memory, not associated with a named variable that already exists. This is helpful in situations like:

1- Dynamic memory.
2- Reading and writing buffers.
3- Accessing hardware devices.

Dynamic memory:

Local variables in functions are automatic variables; the size needed for each function's vars is calculated at compile time and space for all vars is allocated at function call, deallocated at function exit. This is useful for most programs but sometimes we want full control of memory allocation at runtime:
- Perhaps we have an array with non-fixed size.
- Perhaps we're using a linked list; where memory must be allocated only when we need to add to the list.
- Perhaps we're creating an interpreter for our own programming language, where the user's program will allocate memory.

In all cases, memory allocation takes a form like this
myPointer = malloc(memSize);
or
myPointer = new type;
or
myPointer = new type[numElements];

...and I can access the content of the pointer normally with *myPointer = xyz;

We are here using the pointer to store the address of a hypothetical variable that wasn't declared in the code. A 'run-time' variable if we may say. And since they need not be declared at compile time we can have as many of them as we wish and at the time we wish.

I think this has a theoretical aspect; and relates to theory of computation: think of turing machine and the infinite tape that gives them their computational power; and of finite state automatons and the finiteness of their states, as if they were 'compile time' memory :)

anyway...

Reading and writing buffers

Think of the fread function in C:

main() {
Point p1;
fread(&p1,myFile, sizeof(Point));
}

Here the fread function doesn't care if it's reading a point or not: all it needs is a memory location and the number of bytes to read, and it will fill that memory with data from the file. Here the pointer is treated purely as an address.

Accessing hardware devices.

In the good old days of DOS, you could do stuff like this:

// note: just a sample value
#define START_OF_VIDEO_MEMORY 0xA000

main() {
char *v = START_OF_VIDEO_MEMORY;
*(v + 5) = 60;
}

This would write the value 60 at five bytes after the start address of video memory. With code like this a developer could write directly to the video card; do tricks, make fast games....etc.

In modern operating systems this is impossible due to virtual memory. In a system like 32-bit Windows each program sees memory as 4GB all of it available to itself. The operating system does a lot of work to keep programs from taking each others' memory and keep each program thinking it owns all memory on the machine. This means that the address 0xA000 no longer means anything special; it's just a part of the virtual address space that could be valid or invalid for the running process (if it's valid, writing to it will change some unknown part of your program; if invalid your program will crash).

This leads to things like DirectX...etc to make game programming faster on Windows; but does that mean pointers for direct access are no longer useful?

Well, sometimes they're still useful. For example some hardware devices (sensors, robot controllers...) will take the virtual memory system to their advantage; the device's driver will map some memory on the device itself to memory in your program! This means you can use pointers to read or write directly to the device memory. It usually goes like this:

#include "sensor.h"
main() {
char * p = sensor_map_memory( "mySensorDeviceName");
// do what you want with p...
sensor_unmap_memory(p);
}

We've taken a nice journey now, and saw why C has a reputation for being suitable for low-level code; took a look into abstraction and dynamic memory, and hopefully understood pointers at a deeper level. I hope you liked the article!

All about pointers

Everyone, including myself, thought at some time that pointers are some complex, difficult-to-understand feature of C. It's much simpler than you think. You just need to know how the hardware & the C compiler deal with variables.

In C, all data are basically bytes: a char is 1 byte, an int is four bytes, a pointer is four or eight bytes...etc. The difference is what those bytes mean.

Also, during compilation variable names are replaced by numbers. So when your program is being compiled the variable 'x' is replace by (say) 1000. And this number refers to a location in memory.

Let's say your C program is this:

main()
{
int x, y;
x = 5;
y = x;
y++;
}

The compiler will choose an address for each variable (say address of x is 1000, address of y is 1100) and replace all your variable names with these addresses. The machine code generated from the compiler would be like this, in the form of instructions to the CPU:

put 5 into address 1000
read content of address 1000 & put a copy of this content into address 1100
increment the content of address 1100

But those addresses are invisible to us the programmer; we cannot see the 1000, we see only x, right? Well, being a powerful language, C allows us to peek behind the scenes and play with the addresses themselves. This is done via the 'addressOf' operator, also known as &

if I add to the above program
z = &x
it will mean the following (assuming Z is in address 1200):
put the address 1000 in the content of the address 1200

Do you notice a difference? We did not say "read the content of address ....", we directly said "put the address....". This is basically what pointers are: addresses.

The type of z would be a "pointer to int", which means "you know those int variables? I want to store their addresses, not their content". Notice that for int, float, char....etc all pointers are the same size; since all variables are in the same memory space, which has the same type of address.

ok, another example:

main()
{
int x;
int *z;
x = 8;
z = &x;
}

What can we now do with z? We want to read and write to the address it stores. So we can do this:

main()
{
int x;
int *z;
x = 8;
z = &x;
*z = 12;
}

This will generate machine code like this (assume again x is address 1000, z is address 1200; actually you can run this code in debug mode, put a breakpoint, and look at x, z...etc in the watch window; you'll see their actual addresses)

put the value 8 in the memory location 1000
put the value 1000 in the memory location 1200
read the content of the memory location 1200, use that value as a memory location, and go there and write 12

Oh! Did you see that? We did not put 12 in the address 1200, no! We took a peek in 1200, found another address, and went there and put 12.

What was the location written in 1200? It was 1000. And we know that 1000 is actually another name for x. If we did a cout << x we would have found it to be 12 and not 8.

In summary:
  • &a means "the address assigned to the variable a"
  • *b means "read the contents of b, use it as an address for reading and writing".
  • * has another meaning when declaring variables: type *x means x is a pointer to a variable of the type.
All this looks more confusing that it actually is. If you find it confusing, read it again with a pencil and papers, and try to draw memory and its locations/contents.

What is the benefit of all this? It's a long story about abstraction over variables and dynamic memory and more...I discuss it in the second part of this article. Just learn pointers first :)

السبت، 14 يناير 2012

Improving FCIS education: ideas and strategies

الم تتلق العلم في معاملي، وتضحك وتبكي بين جدراني؟
إذن اخبرهم كم أنا جميلة!
كم أنا ذكية!
فقط أحتاج لمن ينفض التراب عن وجهي...
من يجدد شبابي...

Architecture


There's a book called "The elements of computing systems" that attempts to go through all layers of a computer: starting from logic gates and building the hardware, assembler, compiler, operating system, and finally a Tetris game on top. The book even has prepared course material to teach with.

Will it be good? Will it be possible to give in a semester? I don't know, but seems worth examining.

Python, computer vision, and scientific computing

The problem with computer vision/image processing is that the set-up takes much longer than the fun parts. Students spend too much time learning how to load images, access pixels, do transformations,...etc

Python is a very high-level language, with very readable syntax (looks like pseudocode) and a lot of libraries. It currently has a gained a lot of users in the scientific community and got some excellent high-performance, high-quality libraries in these domains. It might be much easier to use in imaging/scientific computing than the current tools (C++, C#) and some researchers are even using it instead of Matlab.

This is a list of common Python libraries for imaging/SC. The most famous is SciPy, described as having "... modules for linear algebra, optimization, integration, special functions, signal and image processing, statistics, genetic algorithms, ODE solvers, and others. "

Another is VTK (visualization toolkit), described as "an open source, freely available software system for 3D computer graphics, image processing, and visualization used by thousands of researchers and developers around the world."

Also, there's SimpleCV, a set of Python libraries to make computer vision easy and straightforward. You can look at their demos if you like.

Perhaps someone can have some experiments with these libraries and try to make use of them in FCIS subjects and/or projects.

Algorithm animation toolkit

I don't know how useful algorithm animation would be in teaching algorithms, but it could be quite useful (algorithm animation = drawing each step in the algorithm one after the other while showing state of variables, content of arrays, ...etc).

I suggest creating a generic algorithm animation kit: it would be an interpreter for a small language (perhaps C-like), the TA would write the algorithm in that language and the interpreter (which knows how to draw an array, a tree, graph...etc) would run each step, visualizing along the way.

It's not that hard a project for someone who knows compilers. By the way it might be even more useful in the data structures course (e.g to explain insertion in a binary search tree) than algorithms.

First year & programming

Let's be honest: there are too many 3rd year students who barely know how to code (probably a lot of 4th year too). Even worse: they haven't learned to make it easy for themselves.

What do I mean, not make it easy? I don't mean object oriented design or such, I mean the really simple things:
  • Indenting code to know where each loop or if statement ends, to have no statement in the wrong place (e. outside the if instead of outside the while).
  • Passing values as parameters instead of storing them as global variables or fields in the class.
  • Giving variables meaningful names. I can't remember how many times I've seen variables called a, a1, c, instead of pixelsPerCentimeter, nameToEmployeeMap,...etc
  • Not trying to really understand the problems, instead randomly changing things until the program seems to run.
  • Not trying to plan their work: no sketching of solutions, no equations before coding, nothing but opening the editor and typing.
These things do not even require practice or extreme intelligence, they simply need to be done.

So how do I suggest solving those problems? We could at least start by:
  • Having TAs talk about these issues.
  • Having TAs code in front of new programmers. All crafts are learned by watching: a young carpenter learns by watching older carpenters. A mechanic learns from his master. Programming might be a science but - like it or not - it's also a craft.
There is this belief among beginners that code is the final product: As if a programmer should read the problem, think real hard about it, and then write the code correctly. In such an imaginary world there is no need to indent code or give variables good names: the code is for the compiler to translate, not for a human to read.

In the real world you'll spend 10 or 20 times as much debugging the code as you wrote it. You'll ask TAs to debug the code with you. Neither you nor the TA wants to get lost in x,c,i,j or wonder where the while loop ends among those braces, or discover that the function depends on a global or member that he forgot about. Just do what you can to make life easier.

Structured programming: the subject that isn't :(

I have a feeling that structured programming has never been taught in the faculty: they always would teach loops or pointers or the like: this is not SP! this is just programming language features.

Real structured programming is about code having structure, i.e being decomposed into smaller components, being able to reason about each component separately of the others, then combining them into a larger program.

This is a sample of the stuff that should be taught in such a course:
  • Decompose programs into functions
  • Functions should be like mathematical functions: takes input from parameters and returns values. Do not call a function by first writing to a global var, calling it, and letting it read from the global.
  • Don't let the function doing the calculation open a file, let each function do a specific job.
  • Don't mix user interface (console or GUI) with the logic. This prevents reuse, among other things.
  • A function should map to a unit of meaning in the problem (e.g draw_character, determine_if_monster_is_dead). Reading code should sound - in your head - like reading the solution of a problem.
  • Think hard about the data, and also decompose it into structs, arrays,...etc. Those should also map to units of meaning in the program (car, deck_of_cards, salary).
Object oriented programming

Among the syntax, the static methods, the class definitions, public & private,...the most important concept is forgotten: objects.

Basically, the idea is that when a program runs, a lot of objects will be created in memory and will interact with each other by method calls. This simple idea - believe it or not - is virtually unknown to a large portion of students.

Don't believe me? Here are the signs:
  • It is very hard to explain to students what static is, even if it means just "Doesn't work on a particular object".
  • It's very hard to explain the 'this' keyword, even if it just means "The object on which the method is called".
  • Students try to call methods on C# forms without having a reference to the form. If compilation fails they create a new form instance instead of acquiring a reference to the active form.
  • They have difficulty getting constructors, which are ways to create objects.
Basically, the students mostly memorize certain shapes of code and write them as-is. So how to solve the problem?

You can start by making sure the basic concept is understood: forget encapsulation, forget inheritance, forget public/private. First you got to make sure they get it:
  • When the program runs, objects are created. They call methods upon each other.
  • An object is not the class; the class is simply an 'algorithm' to create similar objects. All real work is with the objects.
  • When writing a class, think about how the objects created from it will behave.

(This is similar to functions actually: a functions is separate from its activation. This is why the same function can have multiple activations in e.g recursion).

Also, before making them define their own classes, let them use existing classes in the standard library to do basic object operations: creating them, calling methods, setting them as fields in other objects, learn about references...etc

The advice that I just gave can be applied to all subjects in all years: Start with the simplest, most essential concept (structured = decomposition, OOP = objects...) & make sure they learn it before you continue.

Graduation project supervision

It pains me to think about how much knowledge is created, then destroyed all along the years in FCIS.

Think about how many times e.g Ahmed Salah supervised a GP related to computer vision: He recommends papers to students to learn imaging from, then more specialized papers related to the project's domain, then tutorials to Matlab. And then next year students come and he has to repeat the whole cycle again. The day he leaves for his Phd is the day less students will be able to work on CV projects. Why does it have to be like that??

Come on people! I'm not asking for some big, systemic change! Can't we have a Google document online for all TAs to copy & paste the names of papers that they gave to the students?

Then along the years, new students can be pointed to them to learn about the GP domain, interested people like me can use them to learn about new subjects. The information in preserved when the TA is away. New papers would be added if the existing ones get out of date. Wouldn't it be awesome?

The same can be said about code & documentation: We should sort the copyright issues then have all code and docs posted online, and enable searching for projects by name, problem domain (e.g augmented reality) or year. This would solve problems like
  • "Has my project idea been done before?"
  • "Why aren't more projects continued on and improved?"
  • "We want a list of interesting projects to tell TV reporters, to make FCIS more known to society"
What I'm proposing here is accumulated knowledge: Recording previous valuable knowledge so that it can be reused in the future. This is for example why books are such an important part of human progress.

Themes for graduation projects

In 2010/2011 I tried to introduce the idea of themes: a lot of GPs in the same general domain. The aims were:
  • Encourage multiple teams to cooperate on common problems (e.g share papers that introduce NLP).
  • Plant a seed of research groups in the faculty, when some of those students become TA. This would form research groups naturally instead of by fiat from management.
I think this idea should be revisited. Have two or three themes each year, and let TAs announce in a session 10 ideas or so for each theme (but allow students to freely work outside them).

Observation

During my last months as a TA, and in the summer training after I quit, I did something new to myself: I began observing.

I'd sit with the students during a lecture that another TA is giving and see how they react to different styles, or even when do they focus and when they're distracted. If I would do that now I'd also go to the labs and watch how they actually try to program and the things that are repeatedly not understood by different groups of people.

Perhaps as educators we need to take a more scientific approach to teaching, & base our decisions on data instead of personal opinions.

Speaking of scientific, perhaps we could look at research about the topic of teaching programming. For example there's an ACM special interest group called SigCSE (special interest group, computer science education) where relevant papers are published. Also a lot of educators have blogs on the internet, and sometimes they write gems like this for example.

Know your goals

Rarely has an FCIS student been told: what is the purpose of your faculty, and why give those subjects in particular.

To improve the situation, I created this presentation: a tour of almost all FCIS subjects and the purpose of each, both science-wise and market-wise. If you haven't seen it already, I suggest doing so.

Epilogue

I hope some of those ideas turn out to be practical and useful. I think there's much more to be said in this area, and I might write a part II of this article someday :)

الاثنين، 12 ديسمبر 2011

Dreams about metaprogramming in Kalimat

(Note: These are only design thoughts - I do not promise that all or any of those features will actually be in Kalimat).

I'm a big Lisp fan. It seems I can't create a language without trying to turn it into a Lisp. One of the reasons Kalimat got finished in the first place was that I decided to forget all the macros and metaprogramming and try my best to do a good "normal" language.

But now macros call me again...

The first thing I want to add is reified parse trees. I'll make the examples in Kick - the English version of Kalimat - because the Blogger editor has problems with mixing Arabic and English text. But if I implement this it will probably be implemented in Kalimat first.

Now consider this code:
m = myParseTree( )
print m: toString( )

What should be its expected output? Probably something like this:
Program(
statements = [
assignmentStmt(m, functionCall(myParseTree, [])),
printStmt(methodCall(m, toString, [])) ])

Looks like Lisp already :). The program here can see the objects that represent its own parse trees. This has many benefits. For example I can create automatic documentation tools, write code to convert a program into another language, create programs that do code generation or code verification, all without needing to write a Kalimat parser!


Modifying the trees

In a possible next step, I can make the program modify it own parse trees, and enable something like Lisp macros, C++ template metaprogramming, or MetaLua.

What do I mean? Suppose I could mark some functions as special "compile time code". Then I can write a function like this:
compiletime function const(code ~ expression):
code: replace(evaluationOf(code))
end
...and use this function like so:
x = const(sin(0.5) * cos(3) / factorial(3))                      
This will result in the code becoming like this; before the program is compiled:
x = -0.0791046143
Notice what happened: The program's parse tree was modified to replace an expression without variables with its own result (an optimization called constant-folding). This means that during the program's run the expression won't need to be evaluated.

What other tricks can we do? Imagine:
classFromDbTable("person")
classFromDbTable("department")
...and before compilation this code becomes:
class person:
has name, id, department, salary
responds to save(db), load(db)
end

class department:
has name, location
responds to save(db), load(db)
replies to getEmployees()
end
Here the compiler ran the "classFromDbTable" macro, which made a connection to the database, retrieved the needed information about tables and relations, and generated a class for each of the given table with methods to save a record, load a record, or retrieve related records.


Even more dreams

What can we do next? This is an active research area and I don't know if I can/want to implement this; but we could allow certain Kalimat modules to modify the parser before compilation. It means a Kalimat program can define a special version of Kalimat syntax and then we write the rest of that program in the new syntax! For example, if we are developing a game, we can make special syntax for declaring a game character:
syntax character:
codeForm: ...how it should look...
translation: ...actual kalimat code it should become...
end
...and then use the new syntax as if it were part of the existing Kalimat syntax:
character Ship:
image "ship.png"
control = keyboard
ai attack(enemy), maneuver(map)
end

ai attack for ship(enemy):
...implement attack...
end

ai maneuver for ship(map):
...implement maneuver...
end
So, what's the purpose of this article? First: to show you that compile-time meta-programming is cool. Right? :)

Second, to share with you some features I'm considering for Kalimat and hear any comments or suggestions.

Third, this article also answers a question I sometimes get: Why reinvent the wheel implementing a new language with its own parser, compiler, VM...etc. The answer is because Kalimat is not a translation of an existing language: it is a brand new language with its own features, design, and ideas.

الثلاثاء، 6 سبتمبر 2011

Concept: The Whisper programming language

I'm thinking up of a new programming language, heavily derived from Smalltalk and called 'Whisper'. This is an outline of my current thoughts -- I don't know when or if I'd actually implement the language.

Syntax

Like Smalltalk, almost everything is a message send. There are two kinds of message send in Whisper: binary operators and keyword messages. Binary operators follow the usual Smalltalk tradition:

12 + 8 * 2 -- returns 40

Keyword messages follow syntax like this:

myWindow : drawCircleAt(100, 100) withRadius(50)

Some notes:
  • A colon after the object indicates the start of a message send
  • A keyword can have zero, one or more values acting as positional arguments
  • Normal C-like positional arguments are a special case of this syntax
  • The syntax is heavily inspired by the Grace educational programming language, itself inspired - again- by Smalltalk
We have the traditional ST blocks:

myFunc = { x, y | x + y }


When sending a keyword message, and a block is the only argument between parenthesis, the parens can be omitted like so

(x > 5) ifTrue { out : print("yes") } else { out : print("no") }

IDE & Image

As an experiment, the main IDE for Whisper would be completely browser-based with IDE logic running from a web server. Local applications can be written that access local files...etc but the application's UI would still be browser based.

Another, for me much harder experiment is to make everything persistent all the time on an Sqlite database: All program state changes would be by writing to slots in objects, even function activation records or global variables (an idea taken from Self and others), and all slot writes would be trapped and written in the DB.

This would have a very high performance cost, so a lot of design thought should be put into this; by thinking about how to use memory for cache, possibly marking special object as transient, or some other clever method. I'm sure the Lispers, Smalltalkers, Selfers...etc have probably already "killed this problem from research", as the Arabic saying goes, and that I could find an ideal solution in some paper published in 1989..we'll see!

Gradual typing

Fields, method arguments and return values can have optional type declarations, this would allow the JIT compiler to better optimize things and (more importantly for me) allow autocomplete to work. It would also make refactoring safer, for example renaming a method would change the identifiers in all known calls to that method.

This should not change the dynamic nature of the language: The IDE and program are still 'live' and programs are still assembled piecemeal without an edit/compile cycle. There will be situations when calling a method with wrong argument types throws a runtime exception instead of a compiler error, and that's fine for me.

Other goodies

Since I'm now in the dreaming phase and not serious work phase, let's steal some ideas from Lisp, while we're at it:

The first is multiple dispatch. I think this will be useful in certain types of applications like compilers, allow us to think about libraries in new ways (I can imagine a GUI library inspired by the 'lenses' concept from MIT's Haystack project) and allows niceties like the return of traditional syntax:

if(x > 5) do { out: print("yes") } else { out: print("no") }

We can almost fool users into thinking it's Java or C#!

Also, since the syntax is nicely minimal, we could think about adding some metaprogramming...

Since Smalltalk tries to make as much of the program be represented as objects, we can do the same with the program syntax tree itself; and have the AST of each method be a public property of that method.

This would allow us to write code in our own DSL inside a method, code which looks like gibberish to the interpreter but useful for us, since we can write procedures to read the tree from the method and process it in whatever way we like. Possibly layer Common Lisp-style macros on top of this feature.

Looks like a nice language, right? I wish it were already available so that I didn't have to develop it :(

الخميس، 30 ديسمبر 2010

Computer Science and great products

Do you need a good knowledge of computer science to make a great product? It certainly depends on what you're trying to do, but an important point is that the more CS you know the more enabled you are to make useful and impressive software.

The rest of this blog post is a case study in how CS is being used to shape my homegrown programming language for children, كلمات.

First the obvious: It would not have been made without knowledge of compilers. We got that out of the way.

Another thing is that it runs on a small virtual machine called (appropriately) SmallVM. Basically it's a program that reads assembly-like instructions and executes them. Do you know the "basic computer assembler/emulator" sometimes given in computer architecture courses? It's like the big brother of that :)

SmallVM doesn't just run instructions though; it also knows about classes and objects and has a garbage collector. That means it required knowledge about language runtimes in general.

Notice that currently the language runs programs at an acceptable speed. If I want programs to run really fast I need to go deeper: Compiler optimizations, better garbage collection, and perhaps modern VM tricks like polymorphic inline caches.

Do you know that with these techniques a language like Java or C# can reach performance comparable to C++? I hope that I or someone after me learns from those techniques and further improves on Kalimat/SmallVM.

All of this has been about the current version of the language, what about future versions? Here are some ideas I'm thinking about and how computer science can help...

Future idea #1: Gradual typing.

Currently Kalimat is dynamically typed. This means that a variable can take values of any type in the language, and obviously there are no type declarations. This is an example of a program that uses dynamic typing:


Notice how (a) There are no type declarations for the parameters or return value and (b) The program accepts any array of objects as long as each object has a method called نتيجته.

Now I've been thinking: If a child learns my language and afterwards wants to "graduate" into something like C++ ...etc then type declarations and static typing would be new to him or her, but on the other hand if I change Kalimat to require type declarations then it will be harder to teach it to children since the program will require type declarations everywhere, and those will (a) Need explaining (b) Need more syntax memorization and (c) Distract from the actual programming ideas like loops...etc

So the solution? Gradual typing! It means that the language is dynamically typed as usual but with optional static typing. When you declare the type of a variable the compiler will enforce it; otherwise the variable is dynamically typed.

If I decide to implement this feature, I imagine a future version of Kalimat where children would learn programming without being confused by types, and then at some future learning stage they would be introduced to type declarations, watch how the language checks for type errors, and see autocomplete at work!

Future idea #2: GUI programming.

Kalimat currently supports simple graphics like lines and rectangles, but in a future version I hope it supports GUI elements like Forms, Buttons, Textboxes...etc

It would be possible to copy the current event handling models of e.g C#, but I want to take seriously the idea of "a children's programming language". GUI programming is sometimes confusing even for college students! If there's a model that can make it simpler then I should do what I can to seek and use that model.

Again, computer science comes to help! There is a model for parallel programming called CSP, or Communicating Sequential Processes. It started from work by Tony Hoare (the same guy who invented quicksort) and it lead to many implementations and languages. It is also related to the actor model used in languages like Erlang.

So, a couple of days ago I read a paper about how to use CSP to greatly simplify GUI programming. To understand how this works I need to explain a little about the CSP model. Also my explanation is not 100% correspondent to the content of the paper (the idea was further developed in future papers, the paper itself is not current. Also my explanation is simplified).

Imagine that a program is composed of several processes that run independently. To communicate with each other they use a special type of object called a channel. There are two operations associated with a channel:

1- x = receive(ch) ; Which waits until data is available on the channel then returns it in x.

2- send(x, ch); Which waits until some process is ready to receive from the channel and then sends the data in x.

There is also a special command, spawn(p1, p2,...) that launches several processes in parallel.

Now we can talk about GUIs. Suppose we have a graphics application that can be used to draw lines and triangles. If we can assign a channel to each event then we can do this:

Finally we will launch both processes in the main function:


To implement something like this in a traditional GUI library you would need a lot of code in several places. If you studied design patterns you could use the state pattern, for example, to organize your code. But with CSP you write GUI code the same way you think about it. To draw a line you receive two points and join them together. Simple as that.

Now imagine if all this was part of Kalimat.. it would be an Arabic children's programming language that has an easier GUI library than the default library of most modern professional languages!

We need a lot of computer science to implement such a feature. How will we run the processes? Do we use multi-threading and rely on the operating system to schedule the work; or do we modify SmallVM to make it run several processes concurrently and write our own scheduler? Does that mean we will need to revisit what we learned in the operating systems course? :D

Finally

What I want to say in this article is...I'm grateful for all what I've learned in FCIS, without which I wouldn't have been the programmer I am today, that's one thing.

The other thing, and this is important, is that it took me a lot of years learning computer science topics to know all of this. It doesn't have to be about programming languages: Any CS topic; be it operating systems, computer vision, AI, or anything else can open the doors to great products. Products you can use to make money, or improve society, or move science further. But it will take years of hard work and learning.

Why not start now?

الثلاثاء، 19 أكتوبر 2010

Proposal for a new-style FCIS ACM chapter

As some of you know, I have long-term plans of creating a software company, إن شاء الله.

The question is: Where to get great programmers to work there?

What's a great programmer anyway? What types of programmers am I looking for? Think of someone who has some (not necessarily all) of those capabilities:

- Knows enough to create a basic computer vision application.
- Can write a compiler for a small but useful language in a couple of days.
- Can learn a new platform (say a mobile platform) in a short time.
- Invents his own tools to help with projects (e.g code generators, data editors such as level editors in games, verifiers...).
- Understands design trade-offs and the needs for real-world applications.
- Can mix concepts from different disciplines (e.g use techniques from AI when writing a database application).
- ...etc

The reader might now ask: Why do I want such a level of programmers? Does the market need anything like that at all? Well, my plan is to change the market a little. I have big ideas for creative hardware and software applications, many of which I hope are monetizable. Some of them are for internal markets (Egyptian, Arab...) and some for the international market. I should talk more later those projects. Some of their names may be familiar to readers who know me:
- Arwa
- Kalimat
- Awraq
- Kitty
- SketchCode
- Ideaz
- SenseWiki
- ...etc

Isn't this the dream of every computer-science student or graduate? A company where the valuable science they've learned is applied, improved and monetized? A place where you get paid for doing the things you love, and yet produce useful tools for society?

In order to have a chance at doing this, إن شاء الله , many things are needed: I need funding, good strategic planning, and more. But one of the things I'd need most is the existence of a growing number of smart, talented, capable programmers . The existence of those programmers is a major deciding factor for all of this.

How to establish a pool of talent then? Long-term I hope social changes help with this (like teaching children programming). Short-term we need to look at existing students and graduates and help them grow as programmers.

(Are you growing as a programmer?)

Now my opinion on the current FCIS ACM chapter activities. Before I go on I have to say two important things:

1- The ACMers have worked hard to organize competitions and educate students. Many of them have spent long hours of their own time helping others and expecting nothing in return. I'm not trying to discredit their hard work. I think it's clear that they deserve appreciation.

2- I'm not opposing their strategies for the sake of mere opposition. I've talked about these issues with several members of the organization. I think we all have the same goals for the faculty and society in general.

Now..criticism time :-) :-) :-)

1- The current ACM activities make students focus too much on algorithmic problem-solving and almost nothing else. Eventually there's a limit to the usefulness of repeatedly practicing the same topics over and over. After a while you learn nothing new.

2- Then there's no creation involved... The main aim of the competition is to give correct output for a given input. Real-world programming isn't like that. When creating a real product almost nothing is fixed in advance and you need to think hard about features, trade-offs, system constraints and user-interaction.

3- The training focuses almost exclusively on C++ console applications. This is a very small part of the development world. Again, real development has a very diverse ecosystem: Mobile applications, web apps, embedded systems, games, developer tools, scientific applications...etc. All these need a multitude of tools, techniques and languages.

4- The training talks a lot about "Computer science", "Math" and the like yet it only focuses on one aspect of CS and Math ignoring all other important aspects. This could give students the false idea that CS is only about algorithms.

5- ...Even then, the (few small) observations I've noticed make me think algorithms are not really taught in-depth. "Some lessons about graphs and dynamic programming" != "algorithms".

True, the ACMers make the occasional educational sessions or other activities but for me the real goal is achieved when people grow enough as programmers to reach and exceed the level I described at the beginning of this article. Success is when programmers are able to help with the kind of applications I described, for the kind of companies I described. (Yes, I said companies, I hope my own company helps set a wave of change in the local market).

I've talked with some ACM members and leaders and described a proposal for improving the organization. Here's some more details:

The new, new ACM

My proposal for the new ACM is all about changing the focus from one aspect (problem solving competitions) to other suggested aspects:

Creation
Students should train on creating real, working applications and not just idealized programming examples.

Diversity
Students should learn a variety of tools and languages, be capable of creating more than one type of application, and get good introductions to the various fields of computer science.

Depth
Students should have the opportunity of, and be helped with, getting deeper into the subjects that fit with their interests, both scientific and technical.


Activities

Here's a sample of suggested activities that could be made in the new ACM:

Events:-

Hackathons: Where students gather in labs (like in competitions) but instead have 2-3 hours to create a small, useful application. Like a game or a web tool.

Special topic weeks like "software engineering week", "game programming week", "programming language week", where several speakers interested in the same topic can all give presentations about the different sides of that topic.

Minimalist presentation days where several speakers can give sessions, but each session is very focused (say 15 or 20 minutes) so the speakers will have to really concentrate on what's important. And at the same time allow the audience to view many presentations without feeling tired.

Research days where TAs and other researchers can speak about their research and discuss their scientific interests with the audience.

Projects:-

Ongoing open-source projects where fresh members regularly join and learn from experienced members. I think the 2010 summer of code was a real important step forwards in this direction.

Dissect-a-project where a presenter takes some project (open source or developed by the presenter) and explains how it was designed and implemented, with a focus on how design decisions were made, how implementation problem were solved, techniques used, and the like.

Knowledge repositories: An online site where summaries, tutorials and example programs are regularly added and modified. Perhaps also a place to collect technical knowledge from the forum, blogs...etc. Perhaps in the long-term books could be authored that way.

Activities:-

Book rings where (say) five readers take five books, and each reader reads his book then passes it to the next 'element' in the ring.

Sessions of knowledge (مجالس علم) would be like mini-sessions where learners can exchange knowledge, discuss a book, plan for projects...etc

I'm sure that with some brainstorming more and more ideas could be found.

Moving forward

While this discussion is already going with existing ACM members/leaders, I decided to put this article on my blog for several reasons:
  • I wanted to raise awareness of the need for creation, diversity, and depth.
  • I wanted older ACMers (many of whom are outside Egypt) to know about these suggestions and join the discussion if they want.
  • I wanted a stable reference where my ideas are organized, written-down and publicly available.
If something stops improving, it stagnates. I think it's time to take FCIS programming activities (and perhaps the local software market) to the next stage.