Navigation
Wednesday
Oct222008

Using the "Open Recent" Menu in Cocoa without NSDocument

Many people probably already know this, but if you're not using NSDocument in your Cocoa application, the "Open Recent" menu will not get populated automatically when you open files. There are two steps to getting the "Open Recent" menu to work correctly, which are documented in the NSDocumentController documentation, but if you're searching for a way to do this on Google, the NSDocumentController documentation will not come up, and it's not inherently obvious that you should look in the NSDocumentController documentation, and searching the XCode documentation for "Open Recent" returns no results.

First, you need to tell NSDocumentController to add the file to the menu. To do this, you need to call [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL fileURLWithPath:filename]];. You can call this at any time after you have the filename, but it might be best to make sure that you can open the file and read it before adding it to the menu.

Next, you need to implement the - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename method in your NSApplication delegate. This method gets called when the user selects an item from the "Open Recent" menu, so its implementation should open the file or call another method which opens the file. If this method returns NO, the file will be removed from the "Open Recent" menu. If it returns YES then the file will be kept in the menu.

Saturday
Oct042008

Towards an Educational Programming Language for Children

My 10-year-old brother recently asked me to teach him how to program computers. Not sure how to approach the subject, and not wanting to teach him the first language I learned—BASIC—I went looking for programming languages designed to give children an introduction to programming. I found a few, but for one reason or another none of them quite did what I wanted. I then looked into creating my own, and realized that, although implementing an interpreter for a simple programming language may be easy, implementing an educational framework to support it was not.

I don't know if I will ever undertake such an endeavor, but I wanted to post my notes here in the hopes that they would inspire others working on the same problem or create discussions about the problem and its solutions.

Requirements for an Educational Language

In no particular order, I consider the following to be the minimum technical requirements for a successful educational programming language.

  • A simple syntax that encourages best practices without punishing the student for things like incorrect indentation
  • Full documentation, lessons, and problems in both print and online media
  • Support for multiple paradigms, including procedural, object-oriented, functional
  • A syntax that grows with the student's ability
  • A standard library which includes GUI, graphics, sound, networking, database, and multithreading APIs
  • An optional garbage collector enabled by default

  • Clear, descriptive, and helpful errors and warnings
  • A source-level debugger with an animated stack and heap visualizer
  • A testing framework
  • Built-in version control system
  • A completely cross-platform, free/libre open source development environment
  • Not limited to a specific problem domain

These technical requirements facilitate the practice of programming, but for an educational language, additional features can be used to facilitate learning.

  • Short lessons and practice that could be completed in no more than 30 minutes a day
  • Outreach to parents and teachers on the befits of teaching our children how to develop software
  • Training materials and curricula for teachers
  • A collaborative editing environment which allows students and teachers to interact from a distance
  • A moderated community where students could share their programs with each other and the world
  • An easy to install free operating system CD with development environment appropriate for old and new hardware
  • Google Summer of Code-style projects organized by experienced volunteers to allow students to cooperate on useful software

Syntax

One of the most important technical features of an educational programing languages is the ability to grow with the student. This does not mean that the language can be designed incrementally: The language should have a well thought out design and its growth should be carefully directed. Instead, we can think of it more as a collection of related languages which the student progresses through from simplest to most complex.

This growth is important because it ensures that students to not hit a ceiling which prevents them from making the kind of programs they wish to, and does so without throwing all of the complexity of programming on them all at once. If a student found that the programming language is not capable of doing what they want it to do, regardless of whether or not they have the skill to do so, they would become bored and possibly abandon the language.

Early stages of the language could include only one numerical type which encapsulates integers, floats, and complex numbers. At this stage of learning, efficiency wouldn't be a requirement, so this type would not have a minimum or a maximum value. At a later stage, the student would be introduced to separate int, float and and complex types, again without any set minimum or maximum values. Finally, as the student learns about binary representations of numbers, they would be given modifiers to set the size of the numbers.

Strings are also a good candidate for this kind of growth. To simplify things, strings would start out as arrays of Unicode characters. Later on, the student would be taught the differences between many of the Unicode character encodings and given the ability to specify which should be used internally. Finally, the student would be given a string class which represents a sequence of bytes and given the freedom to use it how he or she wishes. During these first two stages the interpreter would take care of any issues that might occur from running the code on different interpreters. That is, if the string is serialized into a file or sent over the network to another interpreter, there would be a standard way of specifying the encoding and the endianness of the data.

In terms of syntax, early stages of the language would be more forgiving than the later stages. The language would be case-insensitive and almost any non-alphanumeric character would function as a general delimiter, so PRINT "Hello World!" would be the same as print("Hello world!") and the same as print[]||| "Hello world!";. Expressions would be separated by line breaks. However, as the student progresses, the rules would become more strict, allowing expressions to expand over multiple lines.

Of course, when introducing bad syntax, it is important to teach better syntax as soon as possible. The point of allowing almost any character as a delimiter is to allow the student to focus only on the lessons being learned without anything else getting in the way. Of course, students would not be encouraged to use any character they want as a delimiter. However, if they accidentally type a period where they meant to type a space, the interpreter would not distract them from the lesson at hand by pointing that out. For the more astute students, the online help would contain an explanation of why these characters do not produce an error.

Environment

The programming environment should consist of a graphical IDE and an interpreter that could be invoked from within the code editor or on its own. The editor should contain online help and documentation, as well as lesson sets to guide the student from the basics of programming to more advanced topics. Because some operating systems are incapable of supporting multiple user accounts or some administrators may not want to set up separate accounts for each student, the editor should allow each student each to create a profile for themselves to keep track of their progress.

The lessons should be short, focusing on introducing one new concept while reinforcing the lessons already learned. Instead of having students implement a large program all in one lesson, it should be broken up into multiple lessons. The short lessons help students to schedule regular programming time and to provide balance in their lives.

The language should include a testing framework to allow the computer to judge the correctness of the student's solutions in the absence of a teacher. Of course, the testing framework would be presented to the student in later lessons to help them test their own programs. The editor should also provide an interface for lesson writers to include hints and propose and explain alternate solutions after the student has written their own solution. The statistics from each lesson, such as time taken, typing speed, number of errors and number of hints used would be saved for the teacher to evaluate how the student is progressing.

The code editor should have a built-in source level debugger which highlights the current expression being executed and provides the values of the variables currently in scope. To demonstrate how the stack and heap work, the debugger should include a visual representation of both the stack and the heap which allows the student to examine the values on the stack and heap. Values on the heap should be highlighted after they are garbage collected, or, in the absence of garbage collection, once there are no more references to those values (i.e. when there is a memory leak). In addition, a graphics and sound explorer should be provided so that the student could check to make sure that the correct graphics and sounds are loaded during debugging. When the student advances to OpenGL, this viewer would contain copies of all the textures currently loaded on the video card.

Version control should be handled within the code editor. It should be automatic at first, but eventually students would be responsible for managing their own source code. The version control database could be hosted on the same computer or on another computer over the network. This would be configured on a per-student basis, and the default could be set for all users.

Teachers should also be able to interact with the students remotely. To accomplish this, the editor should provide a collaborative editing environment, allowing the mentor to connect to the student over the network, track their progress, and help make corrections. If possible, it would be great to also provide text and voice chat.

Outreach

Parent and teacher outreach is an important to a successful educational programming language. Although it would be best if each student could work one-on-one with a knowledgeable mentor, not all children are so lucky. Many will only have access to their school teachers and parents, who may not have the technical acumen to answer questions that students may ask about the lessons. Furthermore, many parents may question whether they want their children spending more time on the computer, and school teachers may question why they should spend their limited resources teaching children how to program computers.

This is partially why lessons should be kept to half an hour per day. It assures parents that their children will maintain a healthy balance with other activities, and many parents already let their children spend some time on the computer playing non-educational games. Shorter lessons would encourage parents to replace some of this time with time for lessons.

Outreach should also include explaining to parents and teachers the benefits of learning to develop software. In addition to preparing their child for a career in the industry should the child want to pursue one, it also fosters an increased understanding of math and science. Lessons should be designed to help improve the students' problem solving abilities and supplement grade-appropriate math and science lessons. For example, elementary students could be asked to implement the long division algorithm, middle school students to develop a program which calculates trajectories of objects thrown at a specific angle and force, and high school students to create a program that helps to balance chemical equations.

In order to be successful in a school setting, the development environment must run on all major operating systems used by schools. Of course, this includes Windows XP/Vista and OS X, but some schools use Linux, and others simply cannot afford to upgrade their computers and still run Windows 98 or MacOS Classic. Although it may not be possible to support every one of these platforms, every effort should be made to do so.

In addition, a CD distribution should be made available to schools which would allow them to either install the development environment on their current machines, install a pre-configured Linux distro on their machine, or boot into said linux distro as a live CD, using the hard drive to store data. This might be difficult on MacOS Classic.

Teachers and parents should be provided with supplementary materials and support to help answer the students' questions. Teachers should be provided with curricula to make their lives easier, and a community should be set up where teachers could post students' questions which they do not know the answer to and receive a courteous reply within 24 hours. If the answer is in the documentation, support volunteers should point that out, but should not be rude about it.

Finally, the community should encourage and solicit teacher input on the direction and content of the lessons. The community should be responsive to teacher suggestions and try to implement them if possible

Community

A moderated online community should be set up to facilitate communication between students and allow them to help one another with problems as well as share to their projects with one another. Each student should also be provided a space to upload their projects to the Web. They could give out the URL of their project to others who, upon visiting that page, could download the source code of the project as well as an executable for their native operating system.

The community should also reach out to get volunteers each summer for Google Summer of Code-style projects. Lead by experienced developers, artists, and organizers, students would be able to sign up for a summer project matching their skill level and collaborate to make a useful program. Again, the commitment of the students would not be more than half an hour a day, and they would be given an assignment each day from the project organizers. Such an assignment could, for example, be one function of the program. If a single student falls behind in their assignments, developer volunteers would be able to step in and implement their assignments so that the rest of the students are not adversely affected. At the end of the summer, the projects would be released to the world and featured on the portal page of the community.

A Note on Internationalization

One of the ideas I came up with was to create a language in which function names and keywords could be translated into any natural language. This obviously introduces some complexities. While it's possible to translate the standard library, it would make it difficult to use libraries created by students in other languages. I am also not aware of any other programming languages with this feature, so I have no model to base my work off of, and it may prevent students from migrating to a real programming language if they are not used to having to work in a foreign language. I originally thought to make early stages of the language work this way, and then to gradually move students towards an English-based language, but I am not sure if this is the right way to go about it.

Friday
Aug032007

MegaHAL Brain Endianness Converter

This post introduces a converter for megahal.brn files which converts files created on big-endian machines (e.g. PPC Mac, Amiga, SunOS) to files usable on little-endian machines (e.g. Windows, Linux x86).

You can get the source and the Windows exe here.

The source is licensed under the GPL v2 (but you can use v3 at your option), just like the original MegaHAL. It's also written the same style as the MegaHAL code, but with different indentation, so you should be able to integrate it into MegaHAL easily if you wish.

At this point, anyone running MegaHAL on OS X had to compile it from source, so I don't feel bad about not providing an OS X executable, despite the fact that I run OS X as my primary OS. Frankly, I doubt anyone will use this, but I feel I've been sitting on the code and it might be useful to someone. If you do require an OS X executable, just leave a comment. The only reason I included the Windows exe was to test out my cross-compiler. You can compile the code with a simple gcc brnconvert.c -o brnconvert .

IMPORTANT NOTE: Do not try to make the output file the same as the input file. I have a check in there to prevent this, but there may be cases it doesn't catch. If you make the input and output files the same, it will just erase the file.

On a less dangerous note, there is a DOS binary of MegaHAL which is being distributed from the official site's /old/ directory. For some reason, it does not write the first byte of the root node of each tree, but other than that it uses the same format. This should break MegaHAL, but it strangely doesn't. I could not find the source code for that version, so my converter will not work with brain files generated by that version. If you have any insight into this problem, please leave me a comment.

I have also included the source of my first converter. I wouldn't use it, and most of the code is from MegaHAL anyway. But if you want to see how the brain file is laid out, the older code makes it more obvious.

Page 1 2 3