JazzScheme

Home News Features Screenshots Tutorials Community Documentation Installation FAQ

FAQ

Build System

Jazz Platform

Jedi IDE

Build System

Do I have to make clean and remake jazz and jedi every time I update from git?

Not at all! A simple 'make' will do.

Here's a quick rundown on what's involved after doing a git pull:

Few changes in a module force recompilation of other modules, because Jazz was designed to minimize compilation dependencies. Some of those changes include modifying a macro, or moving an exported symbol to another module. The build system takes advantage of this and recompiles only changed files. This is why a 'make' will do.

When changes to Jazz require a full rebuild, like when a low-level kernel macro is modified in a way it generates incompatible code, there is a file containing kernel/versions that the build system consults, with entries like:

(version: 201016)                                                     
(version: 201015 gambit-version: 405001 gambit-stamp: 20090827151242) 
(version: 201014 rebuild: all)                                        
(version: 201011 rebuild: kernel)                                     

For example, with the entries above, if your last pull retrieved version 2.01.010, then the '(version: 201014 rebuild: all)' entry above tells the build system it must recompile everything. All this to say that you should never have to worry about it as the developers of Jazz have means to automate rebuilding any parts of Jazz.

A note about the way we implemented dependency-checking to automatically determine when a module's imports have become invalid -- i.e. because some imported symbol was moved or deleted. We had a choice to do dependency checks at runtime, but it would incur a non-trivial cost. So we integrated the check into the build system instead. So it is possible that just launching Jedi after a pull might not work and a 'make' will fix this.

Finally, you should always consult the NEWS file after doing a pull. This is where we describe any breaking changes not covered by the build system and the corrective actions to take. Here's an example:

Release 2.0.21                                                                      
==============                                                                      
Because a slot was added to the Lisp-Entry class, you will need to manually delete  
your catalogs before launching Jedi.                                                

In summary, just do 'make' and have fun. :-)

Can Jazz be built in parallel?

Yes. The number of parallel processes for building can be specified using the jobs: parameter to make (-j -job or j: can also be used).

Here's an example that could be used on a machine with two cores:

% ./jam make jobs: 2 

Another way to specify the number of parallel jobs is to add the following line to $HOME/.jazz/.buildini -- a file that is loaded by the build system:

(jazz.build-jobs 2) 

Can the build system be scripted without using the REPL?

Yes. The build system is fully scriptable. For instance, without entering the build system's interactive REPL, you can configure and build Jazz and Jedi like this:

% ./jam configure -safety release   
                                  
% ./jam make                        
make kernel                       
make core                         
make jazz                         
                                  
% ./jam make jedi                   
make kernel                       
make core                         
make jazz                         
make platform                     
make jedi                         
...                               

Can Jazz be used to build stand-alone executables?

Yes and no. First, lets clarify a few things.

Systems that build applications usually fall into two categories:

  1. Systems that build statically-linked applications where the runtime is statically linked into the application.
  2. Systems that build applications where the application is dependant on a runtime existing somewhere on the client machine.

This may surprise a few, but Jazz falls into first category -- statically-linked applications. The fact that the built executable doesn't contain the code inside the binary but rather as a series of Gambit .o1 files next to it is an unrelated implementation detail. The runtime is there specifically for each application.

Ideally, I see Jazz applications as being either:

  • A minimal binary implementing the kernel + packages containing an .o1 for each of their modules.
  • A minimal binary implementing the kernel + each package linked as a shared library.
  • A statically linked binary which statically includes the kernel and all packages.

The first is the most friendly to developers, the last is the friendliest for end-users, and the second is a nice balance. At the moment only the first is implemented, but we are working on the other two.

Jazz Platform

Is there a binary that can be used to evaluate Jazz code in a non-GUI REPL?

No. Even though Jazz was designed so it can be used independently of Jedi, there is no binary that implements a non-GUI Jazz REPL at the moment. We have started work on that but it is a low priority since it would be a pale substitute for Jedi; for example, a console-based REPL will not be able to handle debugging multiple threads or processes well.

What is the difference between define and definition?

A definition that is public behaves like a define with an export of the definition name.

One of Jazz's design goals is to avoid modifying any Scheme primitive or syntax, so it is not possible to specify access rights (private or public) to a define.

Is there a reference manual somewhere?

A first draft of a complete documentation of the whole Jazz framework is available on the website here.

This documentation is auto-generated from the code and contains the signature of every public and protected declaration.

Why do I get import conflicts?

If a module imports two different modules that each export the same symbol, an error is generated at compile time.

This feature is key in large systems where there are often tens of imports per module, so import order is unimportant.

Where can import and export be used?

Import and export statements can appear anywhere at the top-level of a module. This of course extends to statements inside a top-level cond-expand or begin.

Note that in Jedi, they can be evaluated like any other toplevel form.

How does the runtime locate units?

Units are named with hierarchical names where the components are separated by periods. For instance a.b.c is really the hierarchy (a b c). There are many approaches to mapping units names to persistent OS files. Jazz uses the simple approach of mapping directly onto the directory hierarchy.

In Jazz, the dynamically discovered runtime entities are the packages. Each package defines a root for its units. For a simple example, if there is a package P containing three units -- a, a.b.c and foo -- then the file hierarchy would be:

P/            
  .package    
  foo.jazz    
  a/          
    _a.jazz   
    b/        
      c.jazz  

The above is using the *nix convention for slashes, but the same layout applies on Windows.

A note about the _a.jazz convention: Since a folder cannot contain code, we have a problem when there is both a unit named 'a' and a folder named 'a' in 'a.b.c', as conceptually the code for unit 'a' really goes into folder 'a'. To resolve this, Jazz considers the 'a/_a.jazz' file as 'a.jazz'. So in the previous example, the 'a.b.c' unit could be represented either by 'a/b/c.jazz' or 'a/b/c/_c.jazz'. It would be possible to put the code for the unit 'a' at the toplevel in 'a.jazz' but I find it inelegant that 'a.jazz' and the 'a' folder that is its descendant are two separate objects at the OS's file-system level.

Since a package can contain files other than code -- like documentation and other languages -- it is convenient to specify an arbitrary root. That is what default packages do with the '(root "src")' entry in .package.

What are the programming paradigms available in Jazz?

Jazz supports any mix of the following three:

  • Functional
  • Object-Oriented with Generic methods
  • Object-Oriented with Encapsulated methods

The jazz.sample.paradigms package in the standard distribution showcases the pros and cons of each paradigm through a simple simulation of an LDAP server. Please see the lib/jazz.sample.paradigms/Paradigms.txt file for details.

What is the meaning of a product?

A product is a Jazz concept totally independant of the Jedi IDE.

From the doc:

> A product is the runtime implementation of some user level entity that can  
> be run and built. They correspond to targets in the build system. For       
> instance, when doing 'make jedi', the build system will find the 'jedi'     
> product and ask it to build itself.                                         

A product is simply some Scheme code that registers two functions:

  • one that builds your code
  • one that runs your code

For example, let's say you'd like to run some Mandelbrot code and you name your product 'mandelbrot'. Then:

  • to build your code run: make mandelbrot
  • to execute your code run: kernel -run mandelbrot

For example:

  • Jedi can be executed by running: kernel -run jedi
  • The Connect-4 sample can be executed by running: kernel -run c4

You may be wandering how jazz finds the code. This relates to the repositories / packages / units system. Jedi can create all those automatically for you, so if you do it by yourself you will need to familiarize yourself with how they work. There is some preliminary documentation here.

I also suggest you look at jazz.sample.c4 for a simple example of a package containing a product can be run and that builds an executable.

Is there a way to intercept every event?

Yes, using 'set-shortcut-hook' on the application. Insert the following code snippet in your profile class to try it out:

(method override (test)
  (set-shortcut-hook~ (get-application)
    (lambda (shortcut)
      (debug shortcut)
      #f)))

(method override (test-shift)
  (set-shortcut-hook~ (get-application) #f))

Doing: c-t foo c-p c-n c-s-t will output '{Shortcut #\F} {Shortcut #\O} {Shortcut #\O} {Shortcut :control #\P} {Shortcut :control #\N} {Shortcut :control :shift #\T}' to the console with the above snippet.

The hooking function provided to 'set-shortcut-hook' should return:

  • #f says it wants default handling to occur.
  • #t says it consumed the shortcut, and so stop default handling.

Note that for a finished application, Jazz supports high-level binding tables that associate code to shortcuts. But for fast experimentation or different needs, this hook can be useful. One example is the Tools / View Shortcut Bindings dialog that uses a hook to allow the user to enter a shortcut interactively.

Can every feature of Gambit be accessed from Jazz code?

Yes. Jazz has a new 'gambit' module that can be imported to gain access to every Gambit procedure from Jazz code.

As an example:

(module my-lib jazz

(import (gambit))

(define (test)
  (let ((vec (f64vector 2.0 3.2 4.6)))
    (pp (fl> (f64vector-ref vec 2) 1.0))))

(test))

Note that many of those functions are already exported from the 'jazz' module. Most have the same name, but some have a different name as their underlying code tries to be portable accross Scheme implementations, mainly Gambit, Chicken, PLT and Bigloo.

Why can't I use a @foo variable in my code?

Jazz defines some read-time syntax, and @ is a read-time named comment.

'@wait-bug-fix (define (some-code) ...)' for example.

So using @ is restricted to the above use in Jazz code. However, for this reason Jazz loader consults file extensions so it knows what readtable to use when reading a file. Files with .jazz will use the Jazz readtable while others will use Gambit's default one.

Therefore you can either:

  1. Leave external code in a separate pure Scheme .scm file and load it using (load ...)
  2. Put it in a Jazz unit of Scheme code, also in a .scm file.

The only difference is if your unit is -- as an example -- '(unit external-foo ...)', then loading can be done cleanly by the unit system by adding '(require (external-foo))' as the first declaration of your module that wants to use it.

To access Scheme symbols, use the special form '(native symbol)'. So if your external unit defines 'Foo', put '(native Foo)' somewhere in your module.

If there are many modules that need that symbol, create an export lib. Call it something like 'external-exports', put the '(native Foo)' in it, and have the other modules import 'external-exports' instead.

Is there an easy way to refer to files inside repositories and packages?

Yes. An important role of packages in to enable code location transparency. The unit system allows packages to be moved from one repository to another without having to change any code refering to them; e.g. a package downloaded from an internet repository to a local repository.

This is useful, but to be complete, there must a means to refer transparently to files located inside a package, for example source files and image resources. For this, every repository and package automatically register an alias. As an example an image resource in the 'myorg.mypackage package' can be specified as:

{File myorg.mypackage "images" "someimage.png"}

If 'myorg.mypackage' is moved, all file references will still be valid as the 'myorg.mypackage' alias is dynamically determined by the unit system.

Also, since every file and directory created through the Jedi IDE goes through an anchorizing mechanism to determine the most specific alias available, this means that everything created by the IDE which containing filesystem references -- like the catalogs -- will automatically use aliases for files located inside packages, making them 100% movable with no change to code.

Is there a TODO file for Jazz developers somewhere?

devel/Todo.txt is the main todo file.

Does Jazz include a web framework?

Yes, Jazz has a webserver module.

For an example please look at the jazz.sample.gameserver that comes in the standard Jazz distribution. It is a webserver that implements two simple games, Connect-4 and Gomoku.

To try it out, use the menu item 'Project / Select...' and select 'Game Server'. Although it can run interpreted, I suggest you start by building the project: 'Project / Build' as the AI is quite demanding.

To run the game server accessible at 'http://localhost:8080' there are three methods:

  1. From inside the IDE, select the 'View / Servers' palette and from there double-click the server to start or stop it.
  2. Launch the Game Server project with 'Project / Debug'. The launched process will start the webserver and the webserver's control panel becomes accessible in the Console's 'Game Server primordial' tab.
  3. Or as you would do in production: double-click the 'bin/gameserver.exe' binary that building the project generated. The webserver's control-panel will use the OS console since the process is not connected to the Jedi remote debugger.

Please note that this webserver is a naive implementation not meant for production. It will need more work before being able to serve high volumes although it was rebuilt on the Gambit webserver which offers decent performance.

What options do I have to solve a crash?

Here are a few options:

  • Crash handler

    The Jazz kernel which is the part present in every Jazz application, installs OS code that automatically handles crashes and tries to dump a stack backtrace of all the active threads.

    It does so by handling signals on Unix and by using the SetUnhandledExceptionFilter API on Windows.

    If the system has just begun booting up, the backtrace will be outputted to the standard error, else a file like Jedi_2010-07-05_16-19-42.snapshot will be created in ~/.jazz/crashes. This file can be viewed by a regular text editor but should ideally be viewed by opening it in Jedi where it will be presented in the debugger the same as if the error had just occurred live. Note that because generating a snapshot is a touchy process because the crash may be because of a corrupted state, sometimes the snapshot will only contain partial data up to a point where the snapshot generation crashed again.

  • Using a debug build

    If the crash is due to high-level code crashing (i.e. not a problem crashing inside an FFI call, more something like passing a wrong type like in (car 2) or (append #f '(1 2))), using a debug build is the way to go. By default, the build system when you do 'configure' uses safety: release where many checks are turned off for performance reason (for instance, release mode inserts the following Gambit (declare (not safe)) declaration in every module). To build a debug build, start the build system and do: configure name: debug safety: debug destination: "jazz:debug". Then build that configuration with: make jedi@d. The newly built kernel and jedi executables can be found in build/debug.

If those two don't solve the problem, then it pretty much boils down to being able to reproduce the problem to be able to track the exact cause.

PS: We recently added complete runtime advising to Jazz similar to CommonLisp's defadvice function where the new advise function can be used to advise any function or method, a complete module or even the whole runtime. We plan to use this new functionality to add a precise profiler and code coverage tool to Jazz but maybe it could also be used to automatically track every call being made so we know exactly the last calls made before any crash!

Jedi IDE

Can I evaluate pure Scheme code at the console?

Yes, the Jedi console supports both Scheme and Jazz. Which language is used for evaluation is determined by the current context; you can obtaine that by evaluating ',(in)'. Since Jazz is almost a superset of Scheme, the default context of evaluating as Jazz code usually works just fine.

The various context related command are:

  • ,(in) to display the current context
  • ,(in context) sets the current context to the result of evaluating context where the result can be:
    • #f to set the context to Scheme
    • a symbol to set the context to that unit
    • an object will enable code to access internal fields of that object
    • some special objects have aliases to set them:
      • :me for your profile class
      • :process for the current process

Does the console support the same set of command as the Gambit REPL?

No. The Jazz console doesn't implement the same ',cmd' text-based behaviors that the Gambit console does. It might eventually but it is a low-priority project as almost every command has a Jedi equivalent.

The console does support ctrl-d to clear one level of error since it is useful when you already know what the problem is.

What are the code introspection tools available in Jedi to help me get started?

Getting started in Jazz can indeed be challenging. The good news is that once over first bump it is easy to learn further by example using all the code introspection tools available in the Jedi IDE, as almost everything available in Jazz is used somewhere in Jedi. For instance:

  • You see a button that does something and are wondering how it works:
    • Press F8, move your mouse over the button, right-click and select 'Edit Action' (or 'Edit Action Handler' depending) and you'll be taken to the source code implementing that button.
  • Same thing for menu items:
    • Just open the menu, press F8, move your mouse over the item, right-click, ...
  • If the code you are looking for happens through a shortcut:
    • Go to the Tools / View Shortcut Bindings... menu item (ctrl-shift-k), press the shortcut and double-click the desired binding, and you'll be taken to the source code that implements that binding.

Once in the code it should be simple to navigate further since Jazz catalogs all source-code for definitions and references. First, you might want to make sure your catalogs are up-to-date by going to the Tools / Catalogs Manager window and pressing Update. Note that once this is done, the IDE will maintain your catalogs automatically with any change you make to the source code; you only have to manually update after pulling new changes. When this is complete, put the text selection in any symbol you want and press:

  • F12 to edit that definition or
  • Shift-F12 to view a list of all definitions using that symbol.

Why doesn't my profile load anymore?

When you can't load Jedi due to profile problems, please consult the NEWS file at the root of the Jazz source tree to see if there were breaking changes to the profiles. If not, one solution that will always work is to create a new profile and then compare the new profile's directory content with the broken one. You can use Jedi's Compare Directories tool for this. This should help you discover what change is creating problems.

Can I customize colors?

Here is an example Colors.jml file inside your profile settings directory that will make text and tree backgrounds light purple:

...

  (<Colors-Preferences>
    (<Color-Preferences> name: Text-Background base: Light-Purple)
    (<Color-Preferences> name: Tree-Background base: Light-Purple)
  )

...

Properties available for Color-Preferences are:

  • base - An optional list of color names from which to inherit
  • red - Red part
  • green - Green part
  • blue - Blue part
  • alpha - Alpha component

Note that Jedi catalogs colors so you can use F12 on any color to see its definition and related colors.

Can I customize fonts?

Here is an example Fonts.jml file inside your profile settings directory that will make code fonts 14 point:

For Windows

...

  (<Fonts-Preferences>
    (<Font-Preferences> name: Code      font-name: "Courier New" point-size: 18)
    (<Font-Preferences> name: Code-Bold font-name: "Courier New" point-size: 18 bold?: #t)
  )

...

For the other platforms

...

  (<Fonts-Preferences>
    (<Font-Preferences> name: Code      font-name: 'vera-mono point-size: 18)
    (<Font-Preferences> name: Code-Bold font-name: 'vera-mono point-size: 18 bold?: #t)
  )

...

Properties available for Font-Preferences are:

  • base - An optional list of font names from which to inherit
  • font-name - The name of the font
  • point-size - The point size of the font
  • bold? - Is the text bold
  • italic? - Is the text italic
  • underline? - Is the text underlined

Note that Jedi catalogs fonts so you can use F12 on any font to see its definition and related fonts.

Can I customize styles?

Here is an example Styles.jml file inside your profile settings directory that will make declarations really stand out!

...

  (<Styles-Preferences>
    (<Trait>                  name: declaration
      (<install>                                                  highlight: {Color Light-Red} frame: {Color Red}))
    (<Text-Style-Preferences> name: Text-Declaration              traits: declaration)
    (<Text-Style-Preferences> name: Text-Documented-Declaration   traits: declaration)
    (<Text-Style-Preferences> name: Text-Undocumented-Declaration traits: declaration)
  )

...

Properties available for Text-Style-Preferences are:

  • base - An optional list of style names from which to inherit
  • alignment - The vertical alignment of the text
  • font - The font of the text
  • color - The color of the text
  • highlight - The color of the text background
  • frame - The color of the text frame

Note that Jedi catalogs styles so you can use F12 on any style to see its definition and related styles.

Can I customize skins?

Here is an example Skins.jml file inside your profile settings directory that will use the default skin and draw a gradient in the stage background:

...

  (<Skins>                       active: custom
    (<Default-Skin> name: custom title: "Custom"
      (<stage~>                  background: {Gradient horizontal {Color Red} {Color Blue}}))
    ...
  )

...

Can I customize workspaces?

Yes, Jedi workspaces are fully configurable using the Workspaces.jml file inside your profile settings directory.

You can remove any unwanted workspaces, change the one active on startup, or make any changes you want to those already there.

If the only changes you want to do are splitting a workspace vertically or horizontally, this can be done using the Workspace menu items: Split Vertically and Split Horizontally.