Download · Screenshots · Help. Constructor. Boa Constructor is a cross platform Python IDE and wxPython GUI Builder. It offers visual frame Python is an interpreted, interactive, object-oriented programming language. It is often compared to. The release installation of Boa Constructor can be downloaded in sections The tutorial mostly works, but because of some UI changes, not all of it works as. Tutorial Boa Constructor - Free download as PDF File .pdf), Text File .txt) or read online for free. Diseño de una simple interfaz gráfica con Boa Constructor.
|Language:||English, Spanish, Japanese|
|Genre:||Business & Career|
|Distribution:||Free* [*Registration Required]|
In the last article I explained, what tools you need to build Python GUI's Boa Constructor Download: stocuntutensa.cf The version of Boa available on the Boa Constructor site (http://downloads. Now check out the great tutorial at stocuntutensa.cf designed by Python's. Boa Constructor (see FAQ also) is a cross platform RAD GUI Building IDE download from stocuntutensa.cf
Python is copyrighted but freely usable and distributable, even for commercial use. Well, almost. Other ports are under consideration. As well as providing a common API Application Programming Interface for GUI functionality, it provides functionality for accessing some commonly-used operating system facilities, such as copying or deleting files.
Basic data structures such as strings, linked lists and hash tables are also supported. Scintilla at SourceForge Scintilla is a free source code editing component.
As well as features found in standard text editing components, Scintilla includes features especially useful when editing and debugging source code. These include support for syntax styling, error indicators, code completion and call tips. The selection margin can contain markers like those used in debuggers to indicate breakpoints and the current line.
Styling choices are more open than with many editors, allowing the use of proportional fonts, bold and italics, multiple foreground and background colours and multiple fonts. So if f and g are two functions, their composition is just f g unlike in mathematical notation, functions are read from left to right, so this means first execute f, then execute g. This requires some explanation, since we know functions often have multiple inputs and outputs, and it is not always the case that the output of f matches the input of g.
For instance, g may need access to values computed by earlier functions. But the only thing that g can see is the output of f, so the output of f is the whole state of the world as far as g is concerned.
To make this work, functions have to thread the global state, passing it to each other. There are various ways this global state can be encoded. The most naive would use a hashmap that maps variable names to their values. This turns out to be too flexible: if every function can access any piece of global state, there is little control on what functions can do, little encapsulation, and ultimately programs become an unstructured mess of routines mutating global variables.
It works well in practice to represent the state of the world as a stack. Functions can only refer to the topmost element of the stack, so that elements below it are effectively out of scope. If a few primitives are given to manipulate a few elements on the stack e.
So, functions are encouraged to stay small and only refer to the top two or three elements on the stack. In a sense, there is no distinction between local and global variables, but values can be more or less local depending on their distance from the top of the stack. Notice that if every function takes the state of the whole world and returns the next state, its input is never used anymore.
So, even though it is convenient to think of pure functions as receiving a stack as input and outputting a stack, the semantics of the language can be implemented more efficiently by mutating a single stack.
This leaves concatenative languages like Factor in a strange position, they are both extremely functional - only allowing composition of simpler functions into more complex ones - and largely imperative - describing operations on a mutable stack. Playing with the stack Let us start looking what Factor actually feels like. Our first words will be literals, like 3, Literals can be thought as functions that push themselves on the stack.
Try writing 5 in the listener and then press enter to confirm. You will see that the stack, initially empty, now looks like 5 You can enter more that one number, separated by spaces, like 7 3 1, and get 5 7 3 1 the interface shows the top of the stack on the bottom.
What about operations? The function. Notice that RPN requires no parenthesis, unlike the polish notation of Lisps where the operator comes first, and RPN requires no precedence rules, unlike the infix notation used in most programming languages and in everyday arithmetic. Defining our first word We will now define our first function. Factor has slightly odd naming of functions: since functions are read from left to right, they are simply called words, and this is what we'll call them from now on.
Modules in Factor define words in terms of previous words and these sets of words are then called vocabularies. Suppose we want to compute the factorial. To start with a concrete example, we'll compute the factorial of 10, so we start by writing 10 on the stack. Now, the factorial is the product of the numbers from 1 to 10, so we should produce such a list of numbers first.
The word to produce a range is called [a,b] tokenization is trivial in Factor because words are always separated by spaces, so this allows you to use any combination of non-whitespace characters as the name of a word; there are no semantics to the [, the , and the ] in [a,b] since it is just a token like foo or bar.
The range we want starts with 1, so we can use the simpler word [1,b] that assumes the range starts at 1 and only expects the value at the top of the range to be on the stack.
If you write [1,b] in the listener, Factor will prompt you with a choice, because the word [1,b] is not imported by default. Factor is able to suggest you import the math. Next, we want to take the product of those numbers. In many functional languages, this could be done with a function called reduce or fold. Let's look for one. Pressing F1 in the listener will open a contextual help system, where you can search for reduce. It turns out that reduce is actually the word we are looking for, but at this point it may not be obvious how to use it.
Now, reduce usually takes three arguments: a sequence and we had one on the stack , a starting value this is the 1 we put on the stack next and a binary operation.
What we need is a way to get a word onto the stack without applying it.
Keeping to our textual metaphor, this mechanism is called quotation. To quote one or more words, you just surround them by [ and ] leaving spaces! What you get is akin to an anonymous function in other languages.
This will leave on the stack as expected. We now want to define a word for factorial that can be used whenever we want a factorial. We will call our word fact although! To define it, we first need to use the word :. Then we put the name of the word being defined, then the stack effects and finally the body, ending with the ; word: : fact n -- n!
In our case it is the n -- n! Stack effects are how you document the inputs from the stack and outputs to the stack for your word. You can use any identifier to name the stack elements, here we use n. Factor will perform a consistency check that the number of inputs and outputs you specify agrees with what the body does. If you try to write : fact m n -- n!
We can think at the stack effects in definitions both as a documentation tool and as a very simple type system, which nevertheless does catch a few errors. In any case, you have succesfully defined your first word: if you write 10 fact in the listener you can prove it. Of course, Factor already has a word for the factorial actually there is a whole math. Parsing words If you've been paying close attention so far, you realize I've lied to you.
I said each word acts on the stack in order, but there a few words like [, ], : and ; that don't seem to follow this rule.
These are parsing words and they behave differently from simpler words like 5, [1,b] or drop. We will cover these in more detail when we talk about metaprogramming, but for now it is enough to know that parsing words are special. When a parsing words is encountered, it can interact with the parser using a well-defined API to influence how successive words are parsed. For instance : asks for the next tokens from the parsers until ; is found and tries to compile that stream of tokens into a word definition.
A common use of parsing words is to define literals. Everything in-between is part of the array. Other uses of parsing word include the module system, the object-oriented features of Factor, enums, memoized functions, privacy modifiers and more. In theory, even SYNTAX: can be defined in terms of itself, although of course the system has to be bootstrapped somehow. Stack shuffling Now that you know the basics of Factor, you may want to start assembling more complex words.
This may sometimes require you to use variables that are not on top of the stack, or to use variables more than once. There are a few words that can be used to help with this. I mention them now since you need to be aware of them, but I warn you that using too many of these words to manipulate the stack will cause your code to quickly become harder to read and write. Stack shuffling requires mentally simulating moving values on a stack, which is not a natural way to program.
In the next section we'll see a much more effective way to handle most needs.
Here is a list of the most common shuffling words together with their effect on the stack. Try them in the listener to get a feel for how they manipulate the stack, and explore the online help to find out more. This requires practice getting the function arguments in the right order.
Nevertheless, there are certain common patterns of needed stack manipulation that are better abstracted away into their own words. Suppose we want to define a word to determine whether a given number n is prime.
A simple algorithm is to test each number from 2 to the square root of n and see whether it is a divisor of n. In this case, n is used in two places: as an upper bound for the sequence, and as the number to test for divisibility. The word bi applies two different quotations to the single element on the stack above them, and this is precisely what we need. To continue our prime example, we need a way to make a range starting from 2.
This is one of the modifiers we can use after defining a word, another one being recursive. This will allow us to have the definition of a short word inlined wherever it is used, rather than incurring a function call. Using [2,b] to produce the range of numbers from 2 to the square root of an n that is already on the stack is easy: sqrt floor [2,b] technically floor isn't necessary here, as [a,b] works for non-integer bounds.
Now, we need a word to test for divisibility. A quick search in the online help shows that divisor? It will help to have the arguments for testing divisibility in the other direction, so we define multiple? If we're going to use bi in our prime definition, as we implied above, we need a second quotation.
Our second quotation needs to test for a value in the range being a divisor of n - in other words we need to partially apply the word multiple?. This can be done with the word curry, like this: [ multiple? Finally, once we have the range of potential divisors and the test function on the stack, we can test whether any element satisfied divisibility with any?
Our full definition of prime looks like : prime?
Notice that prime? In general, Factor words tend to be rather shallow, using one level of nesting for each higher-order function, unlike Lisps or more generally languages based on the lambda calculus, which use one level of nesting for each function, higher-order or not. Vocabularies It is now time to start writing your functions in files and learn how to import them in the listener.
Factor organizes words into nested namespaces called vocabularies. You can import all names from a vocabulary with the word USE:. In fact, you may have seen something like USE: math. If you search the online help for a word you have defined so far, like prime? By the way, this shows that the online help automatically collects information about your own words, which is a very useful feature.
On disk, vocabularies are stored under a few root directories, much like with the classpath in JVM languages. By default, the system starts looking up into the directories basis, core, extra, work under the Factor home.
You can add more, both at runtime with the word add-vocab-root, and by creating a configuration file. Generate a template for a vocabulary writing USE: tools. Factor integrates with many editors, so you can try "github. You can add the definitions of the previous paragraph, so that it looks like! Copyright C Andrea Ferretti. You can do this with "github.
There is also a refresh-all word, with a shortcut F2. You will find your editor open on the relevant line of the right file. This also works for words in the Factor distribution, although it may be a bad idea to modify them.
It works like a sort of escape, allowing us to put a reference to the next word on the stack, without executing it. This is exactly what we need, because edit is a word that takes words themselves as arguments. This mechanism is similar to quotations, but while a quotation creates a new anonymous function, here we are directly refering to the word multiple?.
Back to our task, you may notice that the words [2,b] and multiple? It is still possible to refer to words in private vocabularies, as you can confirm by searching for [2,b] in the online help, but of course this is discouraged, since people do not guarantee any API stability for private words.
Words under github. Tests and documentation This is a good time to start writing some unit tests. You can create a skeleton with "github. We will only test the public prime? Tests are written using the unit-test word, which expects two quotations: the first one containing the expected outputs and the second one containing the words to run in order to get that output.
Add these lines to github. You will see that we have actually made a mistake, and pressing F3 will show more details. It seems that our assertions fails for 2. Try making a fix so that the tests now pass. There are a few more words to test errors and inference of stack effects. We can also add some documentation to our vocabulary. Autogenerated documentation is always available for user-defined words even in the listener , but we can write some useful comments manually, or even add custom articles that will appear in the online help.
Predictably, we start with "github. These two vocabularies define words to generate documentation. The actual help page is generated by the HELP: parsing word. Notice that the type of the output? If you now look at the help for prime?
You can also render the directives in the listener for quicker feedback. Have a look at some more with "element-types" help. The object system and protocols Although it is not apparent from what we have said so far, Factor has object-oriented features, and many core words are actually method invocations.
Alan Kay The term object-oriented has as many different meanings as people using it. One point of view - which was actually central to the work of Alan Kay - is that it is about late binding of function names.
In Smalltalk, the language where this concept was born, people do not talk about calling a method, but rather sending a message to an object. It is up to the object to decide how to respond to this message, and the caller should not know about the implementation. For instance, one can send the message map both to an array and a linked list, but internally the iteration will be handled differently.
The binding of the message name to the method implementation is dynamic, and this is regarded as the core strenght of objects. As a result, fairly complex systems can evolve from the cooperation of independent objects who do not mess with each other internals. To be fair, Factor is very different from Smalltalk, but still there is the concept of classes, and generic words can defined having different implementations on different classes.
Some classes are builtin in Factor, such as string, boolean, fixnum or word. Next, the most common way to define a class is as a tuple. Tuples are defined with the TUPLE: parsing word, followed by the tuple name and the fields of the class that we want to define, which are called slots in Factor parlance. The functional minded will be worried about the mutability of tuples. In this case, the field setter will not be generated, and the value must be set a the beginning with a boa constructor.
Other valid slot modifiers are initial: - to declare a default value - and a class word, such as integer, to restrict the values that can be inserted.
Generic words are used to perform dynamic dispatch.
Another way to define a class is as a mixin. If you are familiar with Haskell typeclasses, you will recognize a resemblance, although Haskell enforces at compile time that instance of typeclasses implent certain functions, while in Factor this is informally specified in documentation.
Two important examples of mixins are sequence and assoc. The former defines a protocol that is available to all concrete sequences, such as strings, linked lists or arrays, while the latter defines a protocol for associative arrays, such as hashtables or association lists. This enables all sequences in Factor to be acted upon with a common set of words, while differing in implementation and minimizing code repetition because only few primitives are needed, and other operations are defined for the sequence class.
The most common operations you will use on sequences are map, filter and reduce, but there are many more - as you can see with "sequences" help. Learning the tools A big part of the productivity of Factor comes from the deep integration of the language and libraries with the tools around them, which are embodied in the listener.
Many functions of the listener can be used programmatically, and vice versa. You have seen some examples of this: the help is navigable online, but you can also invoke it with help and print help items with print-content; the F2 shortcut or the words refresh and refresh-all can be used to refresh vocabularies from disk while continuing working in the listener; the edit word gives you editor integration, but you can also click on file names in the help pages for vocabularies to open them.
The refresh is actually quite smart. Whenever a word is redefined, words that depend on it are recompiled against the new defition. You can also save the whole state of Factor with the word save-image and later restore it by starting Factor with.
The power of the listener does not end here. Elements of the stack can be inspected by clicking on them, or by calling the word inspector.
Try clicking on it: you will be able to see the slots of the array and focus on the trilogy or on the string by double-clicking on them. This is extremely useful for interactive prototyping. Special objects can customize the inspector by implementing the content-gadget method. There is another inspector for errors. Whenever an error arises, it can be inspected with F3.
This allows you to investigate exceptions, bad stack effects declarations and so on. The debugger allows you to step into code, both forwards and backwards, and you should take a moment to get some familiarity with it. Another feature of the listener allows you to benchmark code. You will get timing information, as well as other statistics. Programmatically, you can use the time word on a quotation to do the same. You can also add watches on words, to print inputs and outputs on entry and exit.
Another very useful tool is the lint vocabulary. This scans word definitions to find duplicated code that can be factored out.
As an example, let us define a word to check if a string starts with another one. You will get a report mentioning that the word sequence length swapd is already used in the word split of splitting. Now, you would not certainly want to modify the source of a word in the standard library - let alone a private one - but in more complex cases the lint tool is able to find actual repetitions.
It is a good idea to lint your vocabularies from time to time, to avoid code duplication and as a good way to discover library words that you may have accidentally redefined. Finally, there are a few utilities to inspect words.