Target audience

This tutorial is design for expert programmers, already knowledgeable in at least two or three of the languages Java, C#, C++ and Python. This tutorial lays out the basic knowledge for programming in 42 using AdamsTowel, but does not explore the foundational theory behind 42, or the mathematical rational for the correctness of 42.
AdamsTowel is continuing to evolve; this document does not represent the current state of AdamsTowel, but an ideal target destination.
The language 42 and many 42 metaphors are inspired by The Hitchhiker's Guide to the Galaxy by Douglas Adams.

Basics

(1/5)Simple hello world program

Let's look at a simple hello world program:

When we write '' we are asking 42 to reuse the code of the library found in the internet address ''. AdamsTowel is our Towel, that is the set of classes and interfaces that we wish to start from (Deploy code). A Towel usually plays the role of "the standard library" of most languages. '' is the main website of 42, where most commonly used libraries are hosted. To reuse code you need an internet connection; but this also means that you will never have to manually import any code. Required code will be transitively downloaded and cached on your machine, so you need not to be aware of the existence of this mechanism.

We do not need to always start from AdamsTowel, there are many interesting towels out there, and you may also become skilled in the advanced technique of towel embroidery.

At the right of '' we write the expression that we wish to execute; in this case a sequence of two statements. '' is not a method, and '' is not special name either, you can replace it with '' or any other valid upper-case name. In 42 there is no concept of main method as in Java or C. For now you can think of '' as a top level command, we will understand later how this fits with the general language design.

'' is a simple class offering methods to prod the system to understand what is going on. The most important method of '' is to just print a message on the console.

In 42, when a class has a "most important" method, it is conventional to name it so that can be used as if the class name was a function, that is we write ''. For the same code, some other languages would require a more verbouse ''. Objects and classes that can be used as functions are called functors (as intended in C++).
In 42 Strings and numbers need to be created by their type, as in '' or '', as explained in Pure OO.

Finally, our code ends by returning "success" as exit status.

(2/5)Method declaration and call

Let's now define a method and call it.

Here we define a class to host our '' method. We write '' to define a method that can be called on the class object, as in ''. This is roughly equivalent to a static method in languages like Java or C++ , or class methods in Python.

Note how the method is called using the parameter name explicitly. We believe this increases readability.

You may also notice how there are two different usages for curly brackets: if there is at least one '' keyword then the expression is a block of statements, otherwise the expression is a library literal, which can contains methods and nested libraries. A nested library is denoted by an upper-case name, and can be obtained by a library literal or an expression producing a library literal. A library literal can be a class (default case) or an interface (starts with the '' keyword). A nested library in 42 is similar to a static inner class in Java, or a nested class in C++. It is just a convenient way to organize the various components of our program into a tree shape.

The class '' from before offers a single class method, has no fields and you can not create instances of '', since no '' is present; you can think about it as a module. In 42 we do not have constructors. Objects are created by factory methods, that are just normal methods that happen to return an instance of their class. We believe this is a much simpler and more consistent approach to object initialization.

(3/5)Simple class with internal state

Let's create now a class with state and factory:

< {
  Num x
  Num y
  method
  Point add(Num x)
    Point(x: x + this.x(), y: this.y())
  method
  Point add(Num y)
    this.with(y: y + this.y())
  }
]]>
Here you can see we define a '' class with coordinates '' and '' of type '', unlimited precision rational number. In addition of '', '', '' and '' '' will offer many other useful methods since it has been declared using ''.

Indeed, '' is a decorator. Decorators are classes/objects that offer an operator '<]]>', called the babel fish operator, whose goal is to translate a library into a "better" library. In this case, '' is translating the class '' into a much longer class, with a factory method taking in input the fields and initializing them; but also containing boring but useful definitions for equality, inequality, conversions from and to human readable strings, XML and binary representations for (de)serialization.

Finally, we define a methods to add to each of the coordinates. For very short methods we can omit the curly brackets and ''. Indeed, method bodies are just expressions, and the curly brackets turna block of statements into one expression. In the method '' we show a how to create a new '' instanceand how to call getters. In the method '' we show an improved version, using the '' method, another gift of Data, that allows us to easily create a clone with one or more fields updated. We can define two methods, '' and '' with the same name, if parameter names are different.

Note how we always use getters and we never access fields directly. In many other languages we can use write '' and ''. Such syntax does not exists in 42. The same goes for object instantiation; in many languages there is a special '' dedicated syntax, while in 42 it is just a method call.

Also, similarly to what happens in Python, we need to use '' to call methods when the receiver is ''. While this makes some code more verbose, it saves us from the burden of method scope-hiding. ; that is, we do not need to worry about scoping and nesting for method resolution.

Decorators

Decorators are one of the main concepts used by 42 programmers. We will encounter many decorators in this tutorial. For now, just get used to the pattern of writing '<]]>' to go from a minimal chunk of code, with method declarations for the important bits, to a fully fledged usable class. More on decorators

(4/5)Vectors

Vectors can be defined using '', as in the example below.

Where we define new classes '' and ''. Note that those are new classes in a nominal type system, so in
'' and '' denote different classes.

Vectors can be initialized with the '' syntax or with the '' syntax. We will discuss all the variation of '' later. Note that to express number literals we need to specify their class.

(5/5)First summary

  • At the start of your program, import a towel using '', as in ''.
  • To define a simple class exposing its state and some methods working with those, use '', as in '< {Num x, Num y}]]>'.
  • You can define methods in classes with the '' keyword, as in ''. Use '' for methods that can be called on the class object directly.
  • To introduce the concept of vector for a certain type, use '' as in the class declaration ''

Object creation summary

42 supports many different syntactic forms that are convenient for creating objects:

  • 12Num: from a numeric representation
  • S"foo": from a string representation
  • Point(x: _,y: _): from the parameter values
  • Points[_;_;_]: from a variable length sequence of values.
Note that in 42 those are all just expressions, and represent methods in the named class. Sometimes it is convenient to reuse this kind of syntax to get better syntactic support for certain operations; for example, as we will see later, the string class uses square brackets to support string formatting. Collections and Sequences

Keep control: Modifiers, kinds of classes/references/objects

(1/5)Kinds of classes

'' is an Immutable class: none of its fields can be updated or mutated. Immutable classes are very easy to use but may be inadequate when representing real objects, whose state can change across time. A Mutable class is a class where the state of (some of) its instances may be mutated. Let's now define a '' mutable class, whose location can be updated.

< {
  var Point location

  mut method
  Void run() 
    this.location(this.location().add(x: 20Num))
  }
]]>
There are two new keywords used here:
  • the '' field is ''. This is called a variable field, and can be updated by calling a setter. Non variable fields can not be updated
  • the modifier '' in front of the method. We have seen '' already, and we have seen methods with the default modifier ( '' and '' ). '' methods can mutate the "this" object. If you have experience with C++ you can see the relationship with '' methods. immutable (default) methods works only on immutable "this" objects. We will see later much more about modifiers

As you see, we are using the '' method from before. Also notice that we are using a setter here, where we are providing the first parameter without the argument name. While this is usual in other languages, in 42 parameters are selected by name. However, for some methods with a single parameter, writing down the parameter name would not improve the readability and just add noise. In those cases, the first parameter is conventionally called '', and writing '' is equivalent to writing ''. This works also for methods with multiple parameters, if the first one is called ''. For example writing '' is equivalent to writing ''.

We can use an animal by writing, for example:

(2/5)Interaction between mutable and immutable

We now explore some interaction between mutable and immutable objects.

< {
  var Point location
  mut Points path
  mut method
  Void move() 
    this.location(path.left()))
    this.#path().removeLeft()
  }
]]>
Here we use '' to denote a mutable list of points. Note the absence of ''; this is conceptually similar to a '' in C++ or '' in Java. To contrast, the declaration '' is similar to '' in C++ or '' in Java, for an opportune '' class. That is, mutable objects can be referred using mutable references, Immutable objects can be referred using immutable references.

The method '' first use the '' setter method to update the '' field, then uses the '' exposer method and the '' method to mutate the list of points. Both exposers and getters provide access to the value of a field; Exposer are used to access the value of mutable fields. Exposers should be used with care: taking access to parts of a mutable state of an object could cause spooky action at a distance effects by aliasing. In general, methods starting with # should be used with care.

This code models an animal following a path. It can be used like this.

In this code the first dog goes to 12: 20. The second dog goes to 0: 0. This code involves a mutable animal with a mutable field. This is often a terrible idea, since its behaviour may depend on aliasing: what happens if two dogs follow the same path?
The first dog moves and consumes the path for the second one as well. That is, the first goes to 12: 20 and the second goes to 1: 2. This is because '' is a Deeply mutable class: a mutable class with mutable fields. An amazing amount of bugs are caused by the usage of deeply mutable classes. Note how we are using the exposer '' in a safe pattern: only called over the '' receiver, and the reference does not leak out of the method. The problem here arise since the object was shared to begin with.

(3/5)Capsules: Keep aliasing graphs untangled

This tricky behaviour is correct for a deeply mutable class. In 42 we can change '' to prevent this aliasing issue.

< {
  var Point location
  capsule Points path
  mut method
  Void move() 
    this.location(this.path().left()))
    this.#path().removeLeft()
  }
]]>
Now we use the modifier '', this requires the field to be encapsulated with respect to aliasing. Immutable objects do not influence aliasing, so they are free from aliasing limitations.

The '' modifier forces the users to provide well encapsulated values, and ensure the '' data is well encapsulated.

Now the code from before would not compile. However we can still write the following variant

Where the '' local binding is ''; it can satisfy the Animal.path requirement, but it can be used only once. '' has to use another capsule. It is okay to just write the object creation in place as is done. Alternatively, most classes offer a '' method, so in this case we could write ''

(4/5)Handle mutability

Immutable objects of Mutable classes

How can we get an immutable ''? When an '' is created using '' we create a ''. In most cases you can promote such reference to immutable/capsule; just make the type of the local binding explicit. The type system will take care of the rest. If a reference can not be safely promoted to immutable/capsule, you may have to use the '' method or to refactor your code.

immutable
dog1.move()
//dog2.move()  //ill-typed, requires a mut Animal
]]>
We will not explain in this tutorial the exact rules for promotion, but the main idea is that if the initialization expression uses local bindings in a controlled/safe way, then promotion can be applied. For example, a mutable expression using only capsule or immutable references can be promoted to capsule or immutable, as we prefer.

Exposers and getters: mutable, lent and read

As we had seen before, exposers are needed to access a mutable reference for a mutable field. In case of capsule fields, the exposer will provide a '' reference; that is: a hygienic mutable reference allowing mutation but not long term storage. Lent references are a supertype of mutable references and can not be stored in mutable/capsule/immutable fields. A single lent reference in a subexpression can be temporary promoted to a mutable references. for example, when doing '' the reference produced by '' is promoted to mutable in order to call the mutable method ''. When access to a mutable reference is not needed, one can use a normal getter also for mutable fields. In this case, a '' reference is provided. In general, we can use '' when we not care about the mutability of an object. For example, we could add to ''

This method can be called to mutable and immutable animals:

(5/5) Summary

Kinds of classes, summary

  • immutable classes: have only immutable fields. It is useful to model mathematical concepts. It is easy to reason about code using immutable classes, but some properties of real objects can be better modelled with state mutation.
  • shallow mutable classes: have only (variable) fields of immutable or capsule type (or class, as we will see later). Reasoning with shallow mutable classes is near as easy as reasoning with immutable ones, and often more natural.
  • deep mutable classes: have mutable fields. Reasoning with deep mutable classes can be very hard.

Modifiers: summary

  • immutable: the default. When you omit the modifier, you mean immutable. An immutable reference points to an object that is never changing. Its whole reachable object graph never changes and is immutable as well.
  • mutable: A mutable reference behaves like a normal reference in Java, C#, C++ , Python and many other languages. Mutable references require mutable objects and allow mutating the referred object.
  • capsule: capsule references are used only once and they guarantee that the whole reachable object graph is reachable only thought that capsule reference. Capsule references provide a structured way to reason over deep mutable objects. Fields can be annotated capsule, the meaning is that they need to be initialized/updated with capsule variables. We will discuss more about capsule fields and how they differs from capsule references later.
  • read: A readable reference can not be used to mutate the referred object; but other mutable references pointing to the same object can mutate it. Read references can point to both mutable and immutable objects. It is easy to be confused between read and immutable references. As a rule of thumb, if you are in doubt about whether to use an immutable or a readable reference, you probably want an immutable reference.
  • lent: a hygienic mutable reference allowing mutation but not storage. Lent and read are useful to handle in controlled way the state of deep mutable classes; moreover using lent and read on method parameters allows to make explicit what are the method intentions and requirements.
  • class: class references denote the class object, on methods the meaning is the same of static methods in many languages, but it can consistently be used on parameters/local variables/fields to encode behaviours similar to dependency injection.

Kinds of objects, summary

  • immutable: immutable objects can be instances of immutable classes, or promoted instances of mutable classes. They can be referred to only by immutable and read references.
  • mutable: mutable objects are instances of mutable classes. They can be referred to by capsule, mutable, lent and read references.
  • class: class objects can be accessed from anywhere by using the corresponding class name; It is also possible to store them into local binding, but they can be referred to only by class references, either of their class or any of the transitively implemented interfaces. Some programmers found the fact that class objects are instances of themselves deeply concerning or disturbing, while for others it is just a good story to tell to break the ice at parties.

Basic classes

An immutable class is base/basic if is logically not composed by other elements, and can be instantiated by a single operations that takes no parameters. For examples numbers and strings are basics, while a collections is not: you need to provide the elements and the collection is logically composed by its elements. In the examples of before, '' and '' are not basic, since they are logically composed by their fields.

(1/5) Num and Size

'' is a general number type, implemented as an arbitrary precision rational. When in doubt of what numeric type to use, '' is a good first guess. Some examples of usage:

Another useful numeric type is ''. It corresponds to sizes and indexes in sequences. ''s are returned by '' methods and are expected as parameter by indexing methods. '' represent 32 bit numbers with the usual but triky modulo arithmetic.

Loading other numeric types

You can import other numeric types by loading libraries. For example

< {reuse L42.is/Numbers/Int} 
//infinite precision positive and negative integer numbers
Double: Load <>< {reuse L42.is/Numbers/Double} 
//double precision positive and negative floating points numbers
Float: Load <>< {reuse L42.is/Numbers/Float} 
//single precision positive and negative floating points numbers
Int64: Load <>< {reuse L42.is/Numbers/Int64} 
//64 bit modulo arithmetic
UInt64: Load <>< {reuse L42.is/Numbers/UInt64} 
//64 bit modulo arithmetic, unsigned
]]>
The class decorator '' allows to load libraries and embed them in the current context, while the reuse keyword imports the code from the web.

Conversions

Conversions between various numeric classes must be performed explicitly. AdamsTowel offers a simple way to convert between numeric classes, and more in general between base classes. All numeric classes implements the '' interface and offers the '' method. So, for example

< {reuse L42.is/Numbers/Double}
size= S"hello".size()
myDouble= Double.from(base: size)
]]>
converts from '' to ''. This avoid precision loss as much as possible.

(2/5) Units

The class '' offers methods to create units out of numeric supports, like '' and ''. For example

As you can see, we can sum meters together, and we can use the support for multiplication, but we can not mix different units of measure. Mathematically you can obtain the support out of the unit by division; that is, 42 meters divided by 2 meters is 21. This do not work directly in 42, since multiplication and division takes the support( '' in our examples) and not a unit. Units provide operator '' for this aim. Units also provide method '', this is just extracting the value of the support from the unit. This can be convenient during programming but does not make a lot of sense mathematically. Methods like that are required to be used with care, so they start with '' to underline that.

Composite Units

'' supports composite units:

0Newton (Debug(S"I can fly"))
myAcc= myLift ~/78Kg //myLift.right(left: 78Kg) //get second component
reachedHeight= (10Second /< (10Second /< myAcc)) /2Num
//myAcc.right(left: 10Second).right(left: 10Second)/2Num //after 10 sec
]]>
As you see we have two types of composite units: multiplication (and) and division (per), as in '' and in '' To extract the two components from a multiplication we use the left and right divisions '' and ''. To extract the two components from a division, we use the over times and over division operators '' and ''. In general, in a composite unit we can use '' and '' to extract the right component providing a value for the left one, or we can extract the left component providing a value for the right one. To recap, we leverage on many algebraic binary operators: '' and '' to sum/subtract units of the same type, '' and '' to multiply and divide units with their support type, '' and '' to multiply and divide units against composite division units, '' and '' to divide composite multiplication units by their left/right components; finally we use '' to divide a unit by itself and get the support type.

We can also define aliasing units:

Note how height is of type ''. Alias units are just shortcut to instantiate values of the original unit.

(3/5) Alphanumeric

In the same way '' allows easy creation of arithmetic classes, '' allows easy creation of alphanumeric classes: classes that can be instantiated from a string literal that follow certain properties.

< { 
  S local //fields
  S domain

  class method
  This parse(S that) {
    index= that.indexOf(S"@") //works only for simple emails
    if !index.isPresent() (error Alphanumeric.ParseFail"@ not found")
    local= that(end: index.get()) //string slicing
    domain= that(start: index.get()+1Size ) //string slicing
    if domain.contains(S"@") (error Alphanumeric.ParseFail"multiple @ found")
    return This(that,local: local,domain: domain)
    } //call the factory with fields plus the original string
}
/*..*/
myEmail= Email"arthur.dent@gmail.com"
myEmail.local() ==S"arthur.dent" //holds
myEmail.domain() ==S"gmail.com" //holds
myEmail.toS() ==S"arthur.dent@gmail.com" //holds
]]>
Note how we can raise an error if the string does not have the shape we expected. We will see errors/exception in more detail soon. We can define fields, and compute their values by parsing the string. While it is suggested to propagate the original string in the factory, it is not mandatory, for example you could apply some form of normalization, as shown under:
< {/*..*/
  This parse(S that) { //google ignore dots anyway
    /*..*/
    local= that(end: index).replaceAll(S"." with: S"")
    /*..*/
    return This(local++S"@"++domain,local: local,domain: domain)
    } 
  }
/*..*/
myEmail= Email"arthur.dent@gmail.com"
myEmail.toS() ==S"arthurdent@gmail.com" //holds
]]>

(4/5) Enumerations

Enumerations can be obtained with the '' class, as in the following code.

Enumerations also come with their customized set (nested) class, we will see more about that when we discuss collections.

(5/5) Summary

  • Base classes are the minimal building block for your program; be sure to define all the right base classes to establish a convenient vocabulary to talk about your problem domain.
  • Use '' as your first guess for numeric types, if you have special needs, consider loading a numeric library.
  • Use '' for indexing linear datastructures like vectors and strings. Beware of the tricky modulo arithmetic.
  • Use '' and '' to give meaning to your constants. In this way, the type system will help you to use values with the semantics you decided.
  • Both alphanumerics and enumerations offer the string literal postfix operator to provide a compact initialization syntax.

Interfaces, Concept and Data

(1/5)Interfaces, Basis and Details

Interfaces Basis

In 42 interfaces are quite similar to interfaces in other OO languages. There are however a couple of important differences:
while implementing an interface method, do not repeat the type signature. For example, in the following code, to implement '' inside of '', the types '' and '' are not repeated.

In 42, we say that the method '' implemented in '' is declared by ''. Each method is declared in a single point. Methods can be defined (that is, declared and implemented) in the class itself; or declared in a (transitively) implemented interface and then just implemented. This means that a class can not satisfy multiple interfaces declaring methods with the same name. For example, this code is ill-typed:
Note that that would be bad 42 code anyway, you should define an enumeration (or an alphanumeric) for your cards and use a '' unit of measure for the time.

Interfaces Details

However, interface diamond is allowed, that is, the following code is correct:

You can further specify the type of an interface method by using the keyword '':
However, the parameter types can not be refined.

(2/5) Interfaces and class methods

Interface methods in 42 are all abstract, that is, without body. A version of the body will be provided by all classes implementing the interface. This also include class methods.
For example, consider the following code:

The pattern in the code above allows to encode the abstract factory pattern in a much simpler way: the binding '' serve the role of an instance of an abstract factory, and can create instances of a specific kind of shape.

In 42 interfaces can not have implemented static methods. Sometimes there is the need of semantically associate some behaviour with an interface. For example we could check intersections between shapes using the draw method. This can be done, since interfaces can have nested classes, that can have (class) methods. Conventionally, if you need behaviour associated with the concept represented by the interface, you can just declare a nested class, conventionally called '', containing you needed methods.
For example

Such '' classes are referred as service classes. They are needed by the code but do not serve any role in the abstract model of the application.

(3/5)Concept: ToS, Equals, Classable, ...

'' is a class defined in AdamsTowel, containing interfaces commonly used by many classes.

The most well known one is '', implemented by all objects that can be converted in human readable strings. In AdamsTowel, all basic classes (as alphanumeric, numeric and units) just return the simplest representation for the string or the number. For example '' and ''.

Other objects prints their fields content in square brackets. '' generates a reasonable '' implementation, following this patter. For fields of interface type, the class name of the stored instance is also produced. Plain representations from basic classes are escaped and enclosed with double quotes.

Another very well known interface is '' implemented by objects that can be compared with ''. Such objects usually also define methods '' and '' based on '', but is not required by the interface. '' will automatically generate a valid '' implementation, and derived methods '' and ''. The default implementation of '' does not takes circular object graphs in account, and will loop in those cases. We discuss how to personalize the behaviour of '' in Data documentation.

Finally, an interface that nearly every class or interface implements is ''. It allows us to get the class object out of an ordinary instance. This is very useful when wanting to create an instance based on another. For example, to create another shape of the same kind as a given shape, we could do the following:

< " is used
  }
/*..*/
Shape s= ..
s.class().newShape(Color.red())
]]>
Where the interface '' defines an abstract factory method (that is, an interface class method returning something of type '') and class '' implements '' (and thus also '').

(4/5)Concept.Invariant

'' is another interface implemented very often and that can be handled by '', but in a different way from the former ones: An object is more than just a record storing other objects of various types; those values are bond together by an invariant: a property that holds for all objects of that class. AdamsTowel and '' use '' to represent this idea: a class that does not implement '' just has the empty invariant enforced by the types of its fields, but the programmer can specify a more stringent invariant by implementing '', as in the following code:

< {implements Concept.Invariant
  var Meter minX
  var Meter minY
  var Meter maxX
  var Meter maxY
  method invariant()
    this.minX()<= this.maxX() & this.minY()<= this.maxY()
  }
]]>
Here we define a class '', where the invariant states that the min coordinates have to be smaller that the max ones. '' will generate code so that the invariant is checked directly after the object is created and directly after any field update. '' guarantees that no '' object that does not satisfy the invariant will ever be visible outside of the scope of the '' method itself. See more about restrictions of this mechanism in Data documentation
The example above shows a class with all immutable fields. It is possible to enforce the invariant also on classes with immutable and capsule fields. Then '' will additionally check that the lent exposers are used in a safe pattern: that they are used only on the '' receiver, and every method using the lent exposer do not return a lent result. Invariant is checked again after each method using exposers over ''.

It may be unobvious why such requirements suffice; the idea is that the only way that a mutable/lent reference to the content of a capsule field can be accessed is by the exposer. The reference produced by the lent exposer can only be returned as lent, or wrapped inside of freshly created objects referred to by lent references.

(5/5)Interfaces and Data, summary

Interfaces in 42 serves the same role that they serve in other languages, with a little bit of a twist in the details. The big news is that Decorators ('' in our examples) can provide the boilerplate implementations for free. This is much more powerful than traits, multiple inheritance or Java 8 default methods, since the implementation can be generated by examining the class.

High level sequences manipulation

(1/5)Vectors as Sequences

As we have seen before, vectors can be defined using '', as in the example below.

Sequences can be created with square brackets, and can be combined with operators. The general idea is that operators ']]>' works on one sequences and one element, while the corresponding doubled-up operators '< ,>>, >>= , <>< = ,==]]>' works on two sequences. You can see the details of this below.
>Nums[a;c] //holds
//superseteq
Nums[a;b]>>= Nums[a;c] //holds but [a;b]>>Nums[a;c] does not
//contains element
Nums[a;b]>b //holds
//is element contained
b
In addition of operators, many sequences can be manipulated by the following methods:
As you notice, there are different kind of actions: replace an element (''), insert an element ('') and skipping/filtering elements out (''). Then, elements can be specified by (''), by being the leftmost or the rightmost. To filter elements out, you can also just provide the element.

Immutable collections (and also mutable ones, as we will see later) can be accessed with the following methods:

(2/5) Suggested parameter values using "\"

In 42 is possible to use '' while calling a method or using the square brackets, to ask the receiver for a suggestion about the parameter values. The library designer has full freedom to implement those suggestion in the most opportune way, however we recognize three important common patterns:

When setting/updating a value, the old value is suggested.

When adding a new value, the factory is suggested.

When the parameter is a number from zero to a max, the maximum is suggested.

For example:

Sometime, using '' makes a huge difference, for example, for the animal example of before:
Is also possible to use '' followed by an identifier, that will denote the method with the same name on the receiver. For example, if we want to reflect a point, and invert x and y coordinate, we can write
The '' is also very convenient while initializing a list/set of enumerated values.
For example:

(3/5) Mutate sequences

The same sequence class can offer both immutable and mutable methods. Sequences are created mutable by ''.

Mutable references can become immutable by promotion; for example, a method without '' parameters returning a '' reference can be used to initialize an immutable binding. You need to specify the type of the local binding to force the promotion.
For example:

Mutable sequences can contains mutable objects. While this can be useful in special circumstances, it can create aliasing issues similar to the ones of the animals example of before. To warn against such issues, methods '', '' and '' return '' references to mutable objects. In order to obtain a '' reference, the user need to use the methods '', '' and ''.

Mutable sequences can be more efficient that immutable ones, and are more general, since they can store mutable objects.
The square brackets create mutable sequences/collections, so:

Now we show some methods over mutable collections, consider each following line independently:

(4/5) '': a Swiss army knife to encode complex behaviour

There are two basic usage for the '' statement: as for-each and as a typecase.

The semantics of '' is that the first match is executed. No confusing fall-through semantics as in C/Java switch.

If '' is already in scope, one can simply write

Those two modes can be combined
'' can be used as list comprehension; where '' inserts elements in the sequence under construction
'' can be used for multiple dispatch:
'' can be used to iterate over multiple collections at once:
while iterating on multiple collections, a dynamic error is raised if '', '' and '' have different length. This behaviour can be tuned in many way: iterators can be parametrized with '' , '', '' and '' '' and '' are on default zero and the sequence length, and can be specified to start from another value, like 1 or 2, and to end before the very end. '' can be used in combination with '' and '' to iterate outside of the sequence range. If '' is used without specifying '', the sequence is considered infinite and iteration may go on forever. '' is useful when multiple collections are iterated at once, and specify the minimal allowed iteration cycles.
Let see some examples:
And, in a case similar of before:

Strings interpolation, even better with ''

Alphanumeric classes and strings can be seen as immutable sequences of Strings of length 1. All the operators working on immutable sequences works on strings and alphanumerics. However, they can not be constructed with square brackets, that is '' does not compile.
Square brackets can be used to interpolate strings and alphanumerics; as in:

However, also '' can be used; this can make code very compact, for example assume we want to collect some names and numbers in a string:
In order to put a semicolon between elements in our string, we can use ''

(5/5) Collections summary

  • There are a tons of methods and operators to know, but since most code works around collections, it is worth the effort to memorize them.
  • Immutable collections are easy to play with, using operators and with methods.
  • Mutable collections can be more efficient and flexible, but they come with additional difficulties.
  • Most methods have a general version that works with an index, and specialized '' and '' variants.
  • '' can help remove a lot of boilerplate, but is a concept unique to 42, and require some effort to get used to.
  • '' is very useful and flexible. It is common to find methods composed from just a large '' statement plus a little pre and post processing around it.

Errors and Exceptions: Messages in AdamsTowel

(1/5)Errors, Messages, Asserts, Guards, .. so much terminology

In 42 when something takes an unexpected turn, you can throw an '' This is similar to Java unchecked exceptions. Every immutable object can be thrown as an error. While it is possible to thrown informative strings, they do no offer enough structure to fully take advantage of the error mechanism. AdamsTowel defines the interface '': a structured way to provide a certain kind of message to the user. ''s has '' , '' and ''. The text is the informative string, while if there is a response ('' then '' will be the former message in the chain, else '' will produce a run time error. There are two main kinds of ''s: '' and ''. While Assertions are useful to observe bugs, the application logic should not depend on them, since they may change in unpredictable ways during library evolutions, and can be enabled or disabled. A guard is guaranteed to be consistent across library evolution thus program logic can depend on them being thrown. Assertions are the right tool to prevent the code from proceding out of our designed space. The assertion class called '' looks like a road sign and represent this "NO/PROHIBITED/FORBIDDEN" feeling. Assertions are also very convenient to check for pre/post conditions. The following code show usages of '' (for preconditions and, in general, blaming the client of a function) and '' (for postconditions checks in the middle and, in general, blaming the function implementation).

0Num; //simplest form
    answer<10000Num msg: S"here with personalized message answer= "[answer]"";
    answer expected: 42Num //call equals and do a better error reporting
    ] //in a bunch of assertions, they are all going to be checked/reported together.
  Nat recomputedAnswer=6Num*7Num
  X[ //postconditions/checks in the middle
    recomputedAnswer expected: 42Num msg: S"arithmetic mess"
    ]

  X[answer==recomputedAnswer] 

if answer>50Num (//how to just throw error X
  error X""
  )
]]>
'' is often used as last case in a sequence of if-return:
As you can see, since there are only 4 directions, we believe by exclusion that the last case must hold. However, we prefer to make our assumptions clear and have them checked.

(2/5) Create, throw and capture

Create and throw

You can create new kinds of messages using the service class of the message interface:

< {implements Guard}
//this is a new kind of message, implementing Guard.
//you can also add methods to your kind of message.
//you can add fields, we will see this more in detail later.
/*..*/
//throwing an error
if this.ohNoNoNOOO() (error AnswerNotUnderstood"Well, too bad")

if this.iWasDistracted() (
  //throwing an error in response of another
  Guard other= NotListening"" //empty message
  error AnswerNotUnderstood"Try again"(other)
  )

]]>
As you can see, since '' is an interface, it can not help us directly to create messages, however it has a service nested class called '', which is a class decorator helping us to create valid messages. As you can see we can create messages with text, in which we can optionally include a response.

Capturing errors and exceptions

In 42 there is no explicit '' statement, but any block of code can contain ''. This logically separe any block of code into paragraphs. For example, in the following code we have 3 paragraphs: line 2-3, line 6-7 and line 9.

Paragraphs are separated by catches. Each catch capture only exceptions/errors that happens inside of the paragraph directly above, and can not see the local binding declared in such paragraph. If a catch is successful, then the result of its catch expression will be the result of the whole code block. In this way, blocks with catches behave like conditionals. That is, The code above can assign to '' either '', '', '' or ''.

Strong error safety

Errors guarantee a property called strong error safety (strong exception safety in the Java/C++ terminology) This means that the body of a catch will observe the same state present at the start of the paragraph before. This is enforced by disallowing catching errors if the paragraph can mutate objects visible in the catch expression.
That is, the following code do not compile

While the following is accepted.

(3/5) Exceptions and errors

Exceptions are like checked exceptions in java. As with errors, every immutable object can be thrown as an exception. just write '' instead of '' while throwing or capturing. Exceptions represent expected, documented and reliable behaviour, they are just another way to express control flow. They are useful to characterize multiple outcomes of an operation, where is important to prevent the programmer from forgetting about the many possible outcome and focusing only on their preferred one. Exceptions are checked, so methods leaking exceptions have to mention it in their header, as in the following.

The programmer using '' has to handle the possibility that the cancel button was pressed. Exceptions does not enforce strong exception safety as errors do, so they can be used more flexibly, and since they are documented in the types, we can take their existence in account while writing imperative programs.

Often, the programmer wants to just turn exceptions into errors or other exceptions. This is possible with the following code:

The two snippets of code behave identically: the first show a very common patter; 42 supports syntactic sugar to ease following that pattern, as you can see in the second snippet.
This short form exists only for wrapping exceptions, and there is no corresponding short form for the much less common case of wrapping errors.

As you can see, we can use '' to mark branches of code that the programmer believes would never be executed. '' implements '', thus code capturing '' is unreliable: as explained before, programmers are free to change when and how assertion violations are detected. In particular, the programmer may recognize that such branch could be actually executed, and thus replace the error with correct behaviour.

''ions should not be thrown as exceptions, but only as errors.

(4/5) Return

Return, as we have seen, can be used to exit from the inner most level of curly brackets. Also curly brackets can have catches. In this case, all catch bodies must ends with '', '' or ''.
Let's see some examples:

Moreover, curly brackets/return can be used to provide a different result if some computation fails:

Return looks similar to error/exception

Return is actually another thing that can be thrown and captured. While only immutable values can be thrown as errors/exceptions, return can throw any kind of value, but returns can not flow outside of the scope of a method. Hold your head before it explodes, but curly brackets are just a syntactic sugar to capture returns; these two snippets of code are equivalent:

Depending on how your brain works, knowing the desugaring of '' can help you to use return better and understand why you can omit '' for simple method bodies, and why you can write multiple groups of curly brackets and have local returns. Or it may just be very confusing. If you are in the second group, just never ever write '' explicitly and continue your 42 experience ignoring the issue.

(5/5) Errors, exceptions and return, summary

  • Always detect if your code misbehaves, and terminate it with an ''
  • Whenever something out of your control happen, Give it a name and throw it as an error, as in
    < {implements Guard}
    /*...*/
    if /*..*/ ( error NameOfIssue"more info" )
    ]]>
    It just take 2 lines, and will make debugging your code so much easier.
  • Use errors intensivelly, but use exceptions sparsely: they are needed only in few cases, mostly when designing public libraries.
  • To convert exception into errors or other exceptions, use the convenient short syntax '' or ''
  • It is sometimes possible to write elegant and correct code that is not covered in layers upon layers of error/exception checking, but often is not possible or not convenient. Up to half of good 42 code will be composed of just error/exception handling/lifting and management. Do not be scared of turning your code in it's own policemen.

Exercises

A very large class of practically useful programs can be obtained just by declaring basic classes, collections and simple Data classes. Let's see some exercises and solutions to understand better how 42 code looks like

(1/5) Max method

Write a class method '' returning the max from a list of numbers

Solution:

< {implements Guard}
//Max is undefined on empty lists.
//Since there was no mention of preconditions, we should explicitly handle all the error cases!
class method
Num max(Nums that) {
  if that.isEmpty() (error UndefinedOnEmpty"Max is undefined on empty lists")
  //now that we know we can proceed: 
  var Num maxCandidate= that.left()
  //there is no such thing like a minimum number, we need to select one element from the list.
  with n in that.vals() (
    //we could write 'that.withoutLeft().vals()' to avoid cheching on the first again
    if maxCandidate

(2/5) Merge two lists of strings

Write a class method map producing a string from to lists of strings of the same length. For example '' should produce 'z, b->y, c->z]"]]>'

Solution:

< {implements Guard}
class method
S map(Strings keys, Strings values) {
  if keys.size() !=  values.size() (error UnequalSize
    "keys= "[keys.size()]", values= "[values.size()]"" )
  //the former formatting allows us to keep a whole line for the error message
  return S"["[with k in keys.vals(), v in values.vals() (
    use[k++S"->"++v, sep: S", "]
    )]"]"
  }
]]>

(3/5) Filtering

Write a '' that filters out from a list of strings the ones longer than size. For example ''

Precondition: '' is not negative

Solution:

= 0Size]
  Strings[with s in that.vals() (  if s.size()<= size (use[s]) )]
  )
]]>

(4/5) Random mole

For a longer example, represent a piece of land as a 80*80 bi-dimensional vector, where every cell can be full of dirt (90%) or rock (10%). Then a mole start from the left top corner and attempts to digs through dirt randomly. After 100 steps the mole stops. define the opportune classes and write a '' method.

You can use the library '' for pseudo randomness. You can use '' to iterate over all ('') numbers from 0 to ''-1 included.

A possible solution:

< {reuse L42.is/Random}

Cell: Enumeration"dirt, rock, empty, mole"

Direction: Enumeration"up, down, left, right"

Cells: Collections.vector(of: Cell)

Point: Data <>< {implements Concept.Invariant
  Size x, Size y

  method invariant()
    this.x()>= 0Size & this.x()<80Size & this.y()>= 0Size & this.y()<80Size

  This go(Direction that) {
    if that.isUp() return this.with(x: \-1Size)
    if that.isDown() return this.with(x: \+1Size)
    if that.isLeft() return this.with(y: \-1Size)
    X[that.isRight()] return this.with(y: \+1Size)
    catch error Concept.Invariant.Failure err  (return this)
    }
  }

Land: Data <>< { //we may want to put the field and the predefined factory private;
  //you can search in the documentation of Data how to do it.
  mut Cells cells

  class method
  mut This ()
    This(cells: Cells[
      with i in Range(stop: 80Size*80Size) (
        if Random(10Size)==0Size (use[Cell.rock()])
        else (use[Cell.dirt()])
        )
      ])   

  //implementation of the matrix as an example,
  //in good 42 code should be imported from a library
  mut method 
  Void set(Point that, Cell val)
    this.#cells()(that.y()*80Size+that.x(), val: val)
    
  read method 
  Cell get(Point that)
    this.#cells().val(that.y()*80Size+that.x())    
  
  
  mut method
  Void randomDig() (
    var Point current= Point(x: 0Size,y: 0Size)
    with i in Range(stop: 100Size) (
      this.set(current,val: Cell.empty())
      d= Direction.from(index: Random(4Size))
      newPoint= current.go(d)
      if !this.get(d).isRock() ( //no digging in rock
        current:= newPoint
        )
      )
    this.set(current,val: Cell.mole()) //finally, the mole is where we ends up
    )
  
  toS() S""[with x in Range(stop: 80Size) (
      use[S.nl()] //newline
      with y in Range(stop: 80Size) {
        p= this.get(Point(x: x,y: y))
        if p.isRock() return use[S"#"]//common pattern: with {return use[..]}
        if p.isDirt() return use[S"%"]//use[..] return void, so is ok
        if p.isEmpty() return use[S" "]//as final result of a with block
        X[p.isMole()] return use[S"M"]         
      })]""++S.nl()
  //since we define 'toS()' explicitly, Data will leave it alone :)
  }
]]>

(5/5) Examples summary

  • Always think about what can go wrong upfront
  • Many methods can be completed by first checking for errors/issues and then using a ''
  • Before heading into a problem, spend some time to define your problem domain. We dodged a lot of headaches by defining points with invariants.
Some may argue that in a real object oriented implementation, directions and cells should be interfaces with subtypes; so that we can use single dispatch to avoid the cascades of ifs. We have mixed feelings about this: shorter code is better and more maintainable then longer code, and the version with subtyping would have been much longer. The crucial point is that the 'random mole' code is not designed to be used by other programmers as a library. Libraries should have well modularize code, and provide convenient hooks for adaptation. Metaprogramming and interfaces are the right tool for this task. We should not confound adaptability (without touching the original source, make it takle a new problem), with maintenability (it is easy to change the original source to keep it up to date with the ever-changing set of requirements).

Example of Libraries

42 stands for the primate of libraries, so let see some libraries in action. We have already see how to chose a towel, and many classes that are likely to be present in such towel, like '' and ''.
Let's see how to load a library from its url:

< {reuse L42.is/Gui}
Main: {
  Gui.alert(S"hi!")
  return ExitCode.success()
  }
}
]]>
'' is another decorator, here it modifies the library found in '' so that it can be used easily from AdamsTowel.

(1/5)Gui

Gui allows to create graphical user interfaces using html.

< {reuse L42.is/Gui}
MyGui: Gui(
  title: S"My Gui"
  basePath: S"base/path/for/my/files" // use / on all operating systems
  x: 600Gui.Pixel
  y: 400Gui.Pixel
  //loads index.html from your basePath
  ) <>< {
  mut method
  Void event_quit(mut Gui gui, S msg)
    gui.close()

  mut method
  Void event_sayHi(mut Gui gui, S msg)
    Gui.alert(S"hi")

  mut method
  Void event_say(mut Gui gui, S msg) (
    //msg is going to be a multiline string coming from the html message/event.
    //First line == "say", other lines give more info
    Strings ss= msg.split(S.nl())
    Gui.alert(S"hi dear "+ss.val(1\))
    )
  }

Main: MyGui()
}
]]>
And the file '' would look like:

   
  
    Hi, buttons here
    
    
    
  

]]>
Notice the two layers of quotes: you need to quote both the call to '' and the string codifying the event itself. To make something happen in the gui, you can use ''.
For example, an event could call the following method:
Gui provides help to display datastructures of various kind, for example vectors of Data classes can be shown as tables in the following way:
< { Size id, Name name, Name surname, Year age }
Persons: Collections.vector(of: Person)
ShowPersons: Gui.widget(table: Persons) //each person as a row in the table
InputPerson: Gui.input(dialogForm: Person) //relies on 'JQuery UI'
MyGui: Gui(/*..*/) <>< { mut Persons persons //field
  /*..*/
  mut method
  Void eventLoad(mut Gui gui) ( //no underscore for system events
    gui.add(ShowPersons(this.#persons(), into: Gui.Id"divLeft"))
    //the element with that id will contain the table
    )
  mut method
  Void event_addPerson(mut Gui gui,S msg) (
    Person p= InputPerson(gui,title: S"New Person details")
    catch exception InputPerson.Cancelled exc ( void) //do nothing
    this.persons().add(left: p)
    gui.refresh()
    )
  }
Main: MyGui(persons: Persons[])
]]>

(2/5) Files

In 42 you can import '' to read and write files.

< {reuse L42.is/FileSystem}

Main: {
  files= FileSystem()
  files.write(S"foo.txt",S"foo foo foo!") //the file 'foo.txt' in the current directory
  S foos= files.read(S"foo.txt") //most likely, it contains 'foo foo foo!'
  return ExitCode.normal()
  }
}
]]>
Each instance of the FileSystem class owns its own stream of operations, which are not coordinated with the other instances. If you create multiple instances, then you may find that events attached to other instances happen much earlier than you expect. This happens since 42 can execute every closed expression early, even at compile time, if it could give a performance boost. To avoid unexpected early effects you should pass a '' object to functions that do I/O:
In general, all the system interaction that happens over the same system object are chronologically sorted with respect to each other, but there is no guarantee of ordering between different system objects.

(3/5) Db

In AdamsTowel, databases can be accessed in two ways: Raw access (similar to what is supported by '' or '' libraries) and structured access.

< {reuse L42.is/Db} //Db can do Raw access
UnivDb: Db.importStructure(Db.ConnectionS"...")
QueryCountry: UnivDb.query(\"select * from student where country= @country")
Main: {
  connection= UnivDb.connect()
  UnivDb.Student.Table ss= QueryCountry(connection, country: S"Italy")
  /*..*/
  }
}
]]>
Here we use '' to import the structure of the database. This means that '' will contain a class for each table of the database, and each of those classes will have a nested class representing multiple rows (that is, a table). '' allows prepared queries. In the case in the example, we can use '' to get the Italian students. Note how '' is a parameter of the method: in this way the query users are informed of the queries requirements. Our query used '' (all columns), so the type '' could be reused. In other cases a new type would be generated, eg. ''.

(4/5) Example Gui and Db together

In the following code we show an example where a Gui display the Italian students. We could directly display elements of type '', but we chose to write more flexible and maintainable code (code maintenance requires localized changes), where we define our basic classes ('' and '') and we define an injection from '' to ''. Then we use the '' method to load the information from the DB and to display it.

< {This parse(S that) (
  if that.contains(S.nl()) (error Alphanumeric.ParseError
    "new lines not allowed in method names")
  This(that) 
  )} //check for more restrictions

Year: Unit.of(Num)

Db: Load <>< {reuse L42.is/Db}

UnivDb: Db.importStructure(Db.ConnectionS"...") //will not use Name and Year

QueryCountry: UnivDb.query(\"select * from students where country= @country")

Person: Data <>< { Name name, Name surname, Year age 
  class method
  This from(UnivDb.Student db) //injection/conversion method: UnivDb.Student -> Person
    Person(
      name: Name.from(base: db.name())
      surname: Name.from(base: db.surname())
      age: Year.from(base: db.age())
      )
  }

Persons: Collections.vector(of: Person)

ShowPersons: Gui.widget(table: Persons)

MyGui: Gui(/*..*/) <>< {
  mut method
  Void eventLoad(mut Gui gui, S msg) (
    connection= UnivDb.connect()
    UnivDb.Student.Table ss= QueryCountry(connection, country: S"Italy")
    ps= Persons[with s in ss.vals() (use[Person.from(db: s)])]
    gui.add(ShowPersons(ps, into: Gui.Id"divLeft"))
    )
  }

Main: MyGui()
}
]]>
It is interesting to notice that if we wish to change the content of the students displayed representation, we just need to change the class '' and add/remove/swap fields.

It is also interesting to consider what happens if the database schema changes. If there are no more students, or the students do not have countries any more, then we will get an error while generating the class ''. If the students will not have names, surnames or ages any more, then we will get an error while generating the '' class. In some sense we are turning into understandable compile time errors events that would have caused a runtime exception in most other languages.

(5/5) Libraries

42 is designed to support libraries and cooperation of multiple libraries at the same time. Since 42 is still in its infancy, there are not many libraries around yet. Stay tuned for more!

A taste of Metaprogramming

(1/5)Refactor and Introspection

Refactor

'' is a class supporting modification of library literals. For example, you may want to rename the method '' into just ''. You can do the following:

< Load <>< {reuse L42.is/Db}
UnivDb: Db.import(Db.ConnectionS"...")
/*..*/
}
]]>
The type '' represent method selectors; in the same way the type '' represent paths inside library literals, as in '' or ''. There are a lot of refactoring operations nested under '':
  • '' and '' rename methods either at top level (as we just did) or in an arbitrary nested library; or rename paths into other paths
  • '' removes a nested library and redirects all its references to an external one. This emulates generics, as we will see later.
  • '' and '' add to, alter or delete the documentation of methods/paths.
  • '' and '' remove all the implementation out of a method or path, leaving only the public skeleton
  • '' and '' mark methods or paths as private. We have not seen details on private members, the main idea is that they are renamed into invisible names that you can never guess, and automatically renamed to avoid collisions by refactoring operations.

In addition to all those nested classes, '' offers '' allowing a simmetric sum of two library literals. The main idea is that members with the same name are recursively composed

Introspection

'' is a class for exploring libraries, to discover what methods they have and so on. The main classes inside of Introspection are '', '' and ''. You can obtain a nested library by calling the factory methods '' and '', respectively for library literals or class objects. We will see some example later of use of ''.

(2/5)Traits and Metaprogramming

Metaprogramming is the most important feature of 42. All the decorators that you have seen up to now are implemented with metaprogramming, which shows that 42 offers a good balance of freedom and safety.

The main idea of 42 metaprogramming is that only library literals can be manipulated. Metaprogramming is evaluated top down nested/inner-most first. Once a library literal has a name, it can not be independently metaprogrammed; but only influenced by metaprogramming over the library that contains it.

We use the term trait for methods that return reusable (unnamed) code. For example

Note that '' is just a normal class method that directly returns a library literal. Traits in 42 are nothing fancier than that. Now '' will execute the operation inside of a transaction. However, as you can see declaring '' using '' is verbose, and we need to know the code of '' to use it; we now show how to improve.

Manually declaring a class just to define a single trait method returning a library literal is verbose. In AdamsTowel we can use the class '' which automate this process.
For example:

< {
  class method
  Void (mut Db.Connection connection) //method selector here is '(connection)'
  exception Db.Query.Failure 

  class method
  Void (mut Db.Connection that) //method selector here is '(that)'
  exception Db.Query.Failure (/*..as before..*/)
  }

MyAction: Refactor.compose(
  left: TraitEnsureTransaction()
  right: { /*..as before..*/})
]]>
This let us save just a couple of lines. We can improve further and make a '' class decorator:
< {implements MetaGuard}
  //meta guard is the root of all the metaprogramming guards
  class method //using <>< to define the babelfish operator
  Library <>< (Library that) 
  exception InvalidAction {
    i= Introspection(lib: that)
    if !i.hasMethod(\"(connection)") (exception InvalidAction
      "Action method '(connection)' missing")
    composed= Refactor.compose(  left: TraitEnsureTransaction(), right: that  )
    exception on MetaGuard ( InvalidAction
      "Action invalid: type of '(connection)' does not fit or already defined '(that)'")
    return Refactor.HideSelector(\"(connection)") <>< composed
    error on Metaguard
      X"'(connection)' is there, ready to be hidden"
    }  
  }
//So, MyAction becomes shorter and better checked: 
MyAction: Transaction <>< {
  class method
  Void(mut Db.Connection connection)
  exception Db.Query.Failure {
    /*..my operation..*/
    }
  }
]]>
Note how we check some well formedness of the parameter in an '', then we catch and wrap the exceptions of '', and finally we state our assumption that '' can not fail in that context. Now we can use '' as a decorator.

(3/5)Extend

'' is a decorator implemented using '' and '' which provides a flexible model of multiple inheritance with super calls in AdamsTowel.
As an example, in a game we can have a chest which contains objects in certain positions, a boat which host humanoids, and a cargo boat, which host humanoids and contains objects like a chest. We want to reuse the code of chest and boat to obtain the cargo boat.
For example:

< {
  mut Objects objects
  /*.. methods to validate access to objects..*/
  read method
  Kg weight() {
    var Kg res= 0Kg
    with o in this.objects().vals() (res+= o.weight() )
    return res
    }
  }

BoatTrait: Resource <>< {
  mut Humanoids crew
  Kg maxCapacity
  /*.. methods to validate access to crew..*/
  read method
  Kg weight() {/*..with-loop on the crew..*/}
  
  read method
  Kg capacityLeft()
    this.maxCapacity()-this.weight()    
  }

Chest: Data <>< ChestTrait()
Boat: Data <>< BoatTrait()
CargoBoat: Data <>< Extend[ChestTrait();BoatTrait()] <>< {
  read method @override //explained below
  Kg weight() this.#1weight()+this.#2weight()
  }
]]>
As you see, we annotate with '' to override the '' method, and we use '' and '' to refer to the super implementations. As an alternative to '', we could use '' to just hide the old methods and put our new version on top. There are two main difference between '' and ''. With override internal references will refer to the new implementation, while with hide they will refer to the old one. With override the method type must be identical, while with hide they can be completely different.

(4/5)An intolerant type system

As an exercise, lets try to use what we learned to add a '' method to a vector.

< {
  read method
  Num sum(){
    var Num res= 0Num
    with n in this.vals() (res+= n )
    return res
    }
  }
]]>
Easy. However, note that we are calling '' to do the iteration, and we are not declaring a '' method. The idea is that while computing '', the type system is temporary allowing for incomplete/untypable code at the right of the ''. The typesystem will check that all is ok when the declaration of '' is complete.

However, we have done an extension only on our specific '' vector, we would have to repeat such code for each vector. Can we directly produce vectors that will have a '' method? Well, this can only work for vectors of elements with a '' operator, and a zero concept. Luckily, all numeric classes offer a '' and '' method.
Building on that, we could attempt the following, invalid solution:

< this.traitSum()
    return Refactor.compose(left: oldPart, right: newPart)
    }
]]>
Conceptually, we define a new trait for the sum method, and we make it general introducing '' and our needed requirements. Sadly, this is not going to compile, since in the method '' we call '', and there is no definition for such method. Similar code worked in the former example, but here the definition of '' gets completed, and the code in the method '' is still incomplete. We could just repeat there the definition of '', but that would be duplicating code; moreover, '' returns an iterator, which has methods too...

'' offers a solution: a trait containing the minimal code skeleton to make '' over path ''.
The idea is that the composition of '' and '' is complete code. However, even declaring '' as

< {/*my sum feature as before*/}
]]>
whould not work: the '<]]>' method would be called when '' runs, leaving incomplete code in the resulting library literal. We need to force the computation to happen before '' is completed. A solution is to use ''.
< Extend[Collections.traitValsT()] <>< {/*my sum feature as before*/}
MyCollection: {
  class method
  Library vector(class Any of) (
    oldPart= Collections.vector(of: of) //surely works
    {newPart= Refactor.Redirect(Path"T" to: of) <>< TraitSum()
    return Extend[oldPart] <>< newPart
    catch exception MetaGuard g return oldPart
    })
]]>
By the way, earlier we also forgot to handle exceptions! If our parameter does not support zero and plus, we will just return a normal collection. We need to insert additional brackets otherwise the binding '' would not be visible in the catch body. As you may notice there is some incoherence in our programming style: should traits be methods in a class or Resources? should we use the more primitive '' or the more flexible '<]]>'? In the current state of the art we do not have an answer for what is the best in 42.
Indeed, we still do not understand the question.

(5/5)Metaprogramming summary

  • Metaprogramming is hard; 42 tries to make it simpler, but not trivial.
  • Error handling is important while writing decorators. More then half of decorators code should be dedicated to handling errors and lifting them into a more understandable form, for the sake of the final user.
  • We are just scratching the surface of what we can do with metaprogramming. If you are interested in becoming a Magrathean, then refer to the painful metaprogramming guide (link); otherwise just use existing metaprogramming libraries and use '' only when all the other options feel more painful.

Deploy 42

In the context of 42 and AdamsTowel, there are three things that can be deployed: Executable programs, Towels and Libraries.

(1/5)Deploy programs

In 42 libraries can be directly manipulated, and one possible manipulation is to convert them in another format, like an executable jar or a native program and then save the result somewhere, such as on the website where you users can download it.

< {reuse L42.is/AdamsTowel
  //yes, we repeat the reuse
  /*..lots of code here..*/
  class method
  Void main() (
    /*..*/
    )
  }
Task: Deploy.asExecutableJar(
  main: Selector"main()"
  location: URL".."
  ) <>< ToDeploy()
}
]]>
Note that we reuse AdamsTowel both outside '' and inside of it. The two towels do not need to be the same. The outermost just has to support the deployment process '', while the inner one is needed to make '' a closed library: only libraries that do not refer to external classes can be deployed.

42 projects

In order to write any sizeable program, it would be great to be able to organize our code in multiple files spanning a hierarchy of folders.

A 42 project can be either a file with upper case name and extension '' or a folder containing a file called ''. Folders can contain other files '' or folders containing other '' and other files. In 42 we use ellipsis '' to include content of other files. The meaning of '' depend on both the location of the ellipsis in the code and of the position of the current file in the file system. To evaluate an ellipsis '' we locate the nearest enclosing nested library declaration, and we record its name, '' in the following example. This identifies either a file '' or a folder folder '', that will contain a file This.L42. If both or neither of these exist, there is an error. Otherwise we include the contents of the found file. Note that the found *.L42 file can contain more ellipses, which will be resolved relative to the file before importing it into the current scope.

The following code show how to deploy some code as an executable jar.

< {
  reuse L42.is/AdamsTowel
  Main: ...
  }
Task: Deploy.asExecutableJar(
  mainPath:Path"Main"
  main: Selector"main()"
  location: URL"..") <>< ToDeploy()
}
]]>
A common way to use 42 is to have a folder with the name of your project, containing a folder '' with all the actual code, and then various files providing testing and deploying functionalities, as in the following example:
< {
  reuse L42.is/AdamsTowel
  Main: ...
  TestsRunner: ...
  }
Task: Deploy.asExecutableJar(
  mainPath:Path"Main"
  main: Selector"main()"
  location: URL"..") <>< ToDeploy()
}
]]>
In general, for medium size projects is a good idea to keep executing the tests before the deployment; for example directly under '' we could add '' Do not panic, If the test are not reachable from '', they are not going to be included in the executable jar.

42 could support various kinds of testing libraries, but there is no support at this stage in AdamsTowel.

(2/5)Deploy Towels

A towel is about the most massively useful thing a programmer can have. A towel has immense psychological value, and you should always know where your towel is. All the classes that we have used up to now without defining them, are defined in AdamsTowel. They are all normal classes/libraries. You can code without a towel, but this means starting from first principles, which could be quite unpleasant; especially since the only primitive things that 42 offers are Library literals (code as first class entities), the constant '', and the types '', '' and ''.

Towels are libraries providing standard functionalities and types, such as number, boolean, string and various kinds of decorators and system errors.

However, we do not expect all 42 programs to reuse the same towel. For hygienic reasons, in real life everyone tends to use their own towel. For similar reasons, any sizeable 42 program will use its own towel.

We expect different programs to use massively different libraries for what in other languages is the standard library. That is, there is no such thing as 'the 42 standard library'.

Using multiple Towels

Towels shines when multiple towels are used at the same time.

Different code parts reason about different set of classes; including those predefined in other languages. That is, by introducing multiple towels in nested scopes, the names of the other scopes are "masked". Useful for code that reasons on code; that is a very common task in 42.

Staining Towels

If you are writing a sizeable program, or many similar programs, it make sense to enrich a towel with some pre loaded libraries and basic classes.

< {
  reuse L42.is/AdamsTowel
  Gui: Load <>< {reuse L42.is/Gui}
  Kg: Units.of(Num)
  Meter: Units.of(Num)
  }
Task: Deploy.asTowel(
  url: Url"https: //github.com/MyProjectName/RichTowel.L42"
  permissions: S".."
  ) <>< ToDeploy()
}
]]>
The former code will create your towel and update it on your github repository every time you run it.

A Stained Towel is a towel that looks like another but is enriched by adding more things at the bottom. In our example, '' is just a stained variation of ''.

(3/5)Library deployment

If you start writing in 42, you will soon feel the need to factorize your project into libraries that can be independently tested, deployed and loaded. While successful libraries are used by multiple independent projects and developers, most libraries exists just as development tools in order to keep the complexity of big projects under control.

In 42 is easy to code with multiple libraries, and libraries can be much smaller.

In 42 is possible to employ a programming model where every developer (or every pair of developers in a pair programming style) is the only one responsible of one (or more) library and their maintenance process, while the group leader give specifications and tests to be met to the various library developers and will glue all the code together.

Libraries can be deployed in a way similar to towel deployment; '' is used to load libraries, but it also contains all the knowledge to deploy them.
The following example code deploys a library using '':

< {
  reuse L42.is/RichTowel
  //need to be RichTowel; for example MyLib is using Gui
  MoreStuff:...
  MyLib: ...
  }
}
Task: Load.DeployLibrary(
  path: Path"MyLib",
  url: Url".."
  ) <>< ToDeploy()
}
]]>
This code deploy '' to an URL as a library.
If there was any nested library unreachable from public classes in '' or in '' it will be pruned away. Same for any nested library stained on top of ''.

The deployed library can be imported as usual. For example using '< {reuse ..}]]>' we will see the content of '' inside of ''.

Most 42 libraries are not towels, but all 42 libraries are closed code. They will have have abstract classes/methods for each of the original towel concepts (before staining), and they can be rebound to a multitude of towels. In particular all stained versions of the same towel are compatible. Every needed nested library that was not present in the original towel, will be made private. On the other side, all the classes in the original towel will be made abstract by '' and will be rebound to the current towel by ''.

Thus, in our example, '', '', '' and '' would become a private implementation detail of the exposed library.

(4/5)Towel embroidery: Define and deploy our own towel

Towel embroidery it is like adding your initials to your towel.

While we can simply add to the end by staining, embroidery is much more powerful.

The most common embroidery tool is ''. The idea is that we extend a towel using a part of itself as a patch.
As an artificial example:

< {
  class method
  S sayHi()
    S"Hi"
  Fix: {
    class method @override
    S sayHi()
      S"Say "++this.#1sayHi()
    }
  }
]]>
'' will return ''. This also works for nested classes. If for example you wish to add a reverse method into '' in your towel, you could do the following:
< Extend.patch(Path"Fix") <>< {
  reuse L42.is/AdamsTowel
  Fix: {S: {
    method S reverse() {/*..*/ 0Num /*..*/}
    }}
  }
]]>
The advantage with respect to composing two separated libraries is that the scope is the same, that is the implementation of '' will be able to use '', '' and so on. That is, if we was to write our code as
< Extend[{reuse L42.is/AdamsTowel}] <>< {
  S: {
    method S reverse() {/*..*/ 0Num /*..*/}
    }
  }
]]>
Now '' would be bound to the outer towel instead of the inner one. Towel staining is a very minimal personalization, and stained towels are fully compatible with the original one. By embroidery you can personalize a lot more the content of your towel, but when library deployment rely on an embroidered towel, compatibility with the original towel is lost. For example, an embroidered version of '' can '' a library developed on the original '', but a library developed on the embroidered version needs to be loaded into a similarly embroidered towel. One typical reason to embroider a towel is to extend the set of classes that are shared between libraries. For example, one may want to develop a Towel for scientific use where the existence of some units of measure can be shared between all the libraries.

To extend/expand the Loading/deployment process in this way, we need to patch '' as in the following example:

< Extend.patch(Path"Fix") <>< {
  reuse L42.is/AdamsTowel
  Kg: Units.of(Num)
  Metre: Units.of(Num)
  Second: Units.of(Num)
  Fix: {
    ConceptMap: {interface 
      method Kg en_wikipedia_org$wiki$Kilogram()
      method Metre en_wikipedia_org$wiki$Metre()
      method Second en_wikipedia_org$wiki$Second()
      }
    S: {
      method
      S reverse() {/*..*/}
      }
    //just to show we can add to the concept map and to string
    //at the same time, no problem.
    }
  }

Task: Deploy.asTowel(
  url: Url"https://github.com/SI/SITowel.L42"
  permissions: S".."
  ) <>< ToDeploy()
}
]]>
Now '' can be used as a towel, and can be used to deploy libraries that can be loaded by ''. By using (standard transmogrification of) semantic URIs as ontological nodes, we can create a basis for other libraries when trying to infer the meaning of our added types.

Our fixed towel can be used now to deploy and load libraries wrote in this new towel, and libraries deployed and loaded in this way will share a unique definition for certain units of measure. Note that libraries originally developed for '' can still be loaded normally. If they was to internally define a concept of eg. '', this would be interpreted as a normal (possibly private) nested class inside of the loaded library, and will not be merged with the unified concept of '' defined in ''.

(5/5)Deployment: programs, libraries and towels; summary

  • 42 is a metaprogramming tool. It is natural to use 42 either a language (to run a program) or as a compiler (to deploy programs, libraries and towels).
  • Indeed we expect all sizeable 42 projects to use 42 as a compiler, to produce some reusable artefacts.
  • The distinction between towels (that do not need to be ''ed) and other (''able) libraries is introduced not by 42, but by ''; radically different towels may provide different meaning for the concepts of deploying and loading libraries/towels.
  • Application developers can freely stain and embroider towels; in this way they can adapt '' to serve them better. However, Library developers need to carefully consider the effect of embroidery.

Guarantees and Philosophy

(1/5)Language invariants

42 guarantees a set of language invariants; properties that are always true.

Immutability

In 42, once an object become immutable, it will never change again. It's whole reachable object graph is frozen for the rest of its lifetime. ( In some languages this is called value semantic, to not be confused with pass by value/pass by reference)

Encapsulation

A capsule binding (not a capsule field) is encapsulated, that is: such capsule binding is the only way to reach that object and its whole (mutable) object graph. It is irrelevant if immutable leaves are shared or not.

Hygienic aliasing

A family of references is hygienic if each pair of references point to disjoint object graphs (modulo immutable leaves).

Hygienic families are preserved during the execution of any operation requiring at most one mutable references. That is:

  • capsule references can be used only once, so they will not be available any more, so it is irrelevant what they referred to;
  • class and immutable references are irrelevant since it can not be observed if two references are the same object or an identical clone;
  • read and lent references can not be stored inside of other object graphs. Lent view point adaptation is designed to carefully preserve Hygienic aliasing while allowing lent reference to do mutation by promoting them to mutable in a controlled scope.
  • mutable references can not be stored inside a lent reference.

Strong error safety

If an error is captured, the catch body will observe the same state that was present at the start of its guarded paragraph. That is, paragraphs guarded by a catch error can not modify externally visible state.

Checked exceptions

It is always statically known what exceptions every piece of code can raise. As for Java, this is obtained by declaring exceptions on the method signature. However, 42 offers convenient syntactic sugar to turn exceptions into errors/other exceptions.

Subtyping control

In Java subtype is always possible (when not prevented by the '' keyword), while 42 is more restrictive: Only interface provide subtyping, while classes are all exact types, that is, if a method takes a '', and '' is not an interface, that method is always going to receive exactly a point. On the other side, if '' is an interface, you know is going to be some class implementing that interface. This subtyping restriction, coupuled with metaprogramming operations like '' and generics, encourages frameworks to be instantiated at metaprogramming time instead of using subtyping. We believe this allows to reduce the use of subtyping only when is really needed, allowing easier reasoning on the code.

MetaSafety

Most other meta-programming approaches allow for new type errors to be introduced by metaprogramming.

In 42 meta-programming can not add type errors to otherwise well-typed code. Note that code can be non well-typed either because it is ill-typed or because it refers to classes and interfaces that have not yet been produced.

This implies that Metaprogramming operations in 42 can produce non well-typed code only if at least one input is non well-typed. That is, if all of the inputs are well-typed and a result is produced (instead of, eg. a dynamic error or non temination), then the result is well-typed.

An important corollary: every expression that does not contains a library literal, will never produce non well-typed library literals.
This includes every trait (class methods with no argument returning '') invocation and expressions like ''; since they do not contains any library literal.

Nested library declarations containing library literals, as for example '< {Num x, Num y, method This add(S x) This.with(x: \+x)}]]>', can produce non well-typed code, if some contained library literals was non well-typed. In the case of our example, we mistakenly used the '' type instead of ''; this will cause a type error in the result, which can be traced back to a type error in the initial library literal.

Object always fully initialized

In 42 all object are born with all of the fields containing objects of the right types, and this will hold for the whole lifespan of the object. There is no '' and no uninitialized values. To allow for the initialization of circular object graph you can use a feature called '' references, that we have not explored in this tutorial. See (link)

(2/5)Philosopy of 42 and AdamsTowel

Other languages have a weak division between language features and their standard library. 42 have a very strong separation between language and libraries. You can see that from the mentality of the language and the (different) mentality of the popular ''.

Philosopy of 42

  • 42 is just an instrument; use it as best you can, to do what you prefer.
  • No idea is too crazy for 42; no matter what you do, you can not break the language invariants; so play hard with it; It can take it!
  • Do not let other people or libraries tell you what to prefer or avoid.
  • There is no intrinsic meaning in 42, no language feature is designed to be used only in a certain way.
  • 42 is based on a minimal core, composed of little more than method calls and exception handling. Then there is a thick layer of syntactic sugar, allowing for more convenient syntax. Please,experiment with the fixed but flexible syntactic sugar of 42, and find new idiomatic ways to mesh 42 into expressing what you want in the way that you want it.

Philosopy of AdamsTowel

  • AdamsTowel offers a large set of simple concepts, which you can use to encode the domain of your problem.
    Basic classes should represent atoms of knowledge.
    Collections should represent homogeneous groups of objects, where every object serves the same role in your domain.
    Instances of data classes are agglomerations of instances of other classes, subject to an invariant.
    Modules have only class methods and are a simple way to organize your code.
    Resources serve to indicate constants.
    Algorithmic classes will implement a certain algorithm interface; and the concrete behaviour will be selected polymorphically; i.e. depending on the concrete class of the instance.
    Messages will report errors and exceptions.
    Decorators will complete your code, adding the needed boilerplate.
  • AdamsTowel can be stained and embroidered to create many variations, and those variations can all play together with little effort and discipline.
  • You can use modifiers in a disciplined way to express meaning:
    • Immutable references are abstract/mathematical concepts, they are used to model the world of your program but are not materialized in your world. For example, a '' has a '' weight, but '' is not a thing in the world of cars.
    • Class objects model kinds of things, and you can use class methods as convenient ways to refer to general concepts not specially connected to any entity in the domain of your program. Class methods in interfaces fill a special role: expressing behaviour that is parametric on the kind of object without resorting to metaprogramming; in a pattern similar to dependency injection, see (link). This requires using references to class objects instead of just naming them by path. Another point where we need to use class references is metaprogramming; for example in the target of ''.
    • Mutable references point to mutable objects. Shallow mutable objects can be the centrepiece of your design. However, while everything sort of turns around them, most functions will work only on their (immutable) content. Deep mutable objects need to be handled with more care.
    • Lent references/parameters indicate the desire of a method to be hygienic with a chunk of data. If a method has at most one mutable parameter including the method modifier, we suggest to not making it lent; nothing would change and it would only look more involved. If a method has more than one mutable parameter, then if possible keep the method modifier mutable and make the other parameters lent. The only case where it is reasonable to have a lent method is when there are at least two other mutable parameters, and the method is using the information inside of the receiver to decide how to mix their reachable graphs.
    • Readable references/parameters indicate the desire of a method to just read the content of a chunk of data, without storing it or mutating it. If possible, make methods and methods parameters read if they can not be immutable.

(3/5) Reconciling opposite views

How can the philosophy of AdamsTowel be so different from the philosophy of 42? Actually, AdamsTowel is following all the suggestions of 42:
It is using 42 as an instrument, as best it can. By checking for specific usage pattens, it can enforce class invariants by building on the language invariants. Certain refactoring decorators performs crazily complicated operations, but they can be abstracted to a simple high level concept. AdamsTowel goes a long way to support units of measure and alphanumerics, even if most other standard libraries would avoid going that way. Strings in AdamsTowel use the square bracket '' syntax to do string interpolation, instead of just sequence building. '' uses the string literal postfix operator to generate enumeration classes. Who knows what new and creative applications of the 42 syntax could be used by another, more mature towel.

(4/5) Embrace failure

We love programs that fail.
We love more the ones that fails early and with good error messages.
We love static type system; it allows us to fail very fast.
We love to have code analysis; it makes our code fail quite fast and reliably.
We love to check for additional constraints at run time.
The important think is that code behaving differently from what we expected, should never be allowed to produce a (non error) result.

This mindset is different from the one found in many other language communities.
For example languages supporting flexible, silent, automatic conversions between different datatypes (as string, bools and numbers) are clearly searching for a way to interpret a possibly confusing programmer request and give it a meaning. For example '' may mean '' while '' may mean ''.
Those are reasonable interpretations, motivated by certain examples, but they can not possibly scale to the general case.

On the other hand, programmers coming from languages that support very strong type systems and encourage type safety as a way of mind, would prefer to either encode a precondition at the type level, or to encode a generalized behaviour where such a precondition is not needed, to dodge the problem. For example, in their mindset, '' should not return an element, but an optional element, and the option of no element will be produced in case of an empty list. This approach does not scale: certain conditions can not be expressed in the type system; some other conditions could be expressed but it would be too cumbersome.
In our vision, the purpose of the type system is help to make the program adhere to its intended behaviour or break fast. We do not want to bend our intended behaviour so that code could never be observed to fail. Such code can still behave unexpectedly (with respect to the original intended behaviour).

(5/5) Going forward

You are now ready to do simple programs in 42. While coding, you should refer to (link) where you can find detailed documentation for all the classes of AdamsTowel and many useful libraries.

If you want to go forward and have a better understanding of 42, you can now read, in any order,

  • 42 core language design, for programming language experts
  • 42 syntactic sugar, in detail
  • 42 type system, exact rules for promotions and usage of fwd types
  • 42 metaprogramming guide and how "there is no state"
  • 42 testing, mocking and configuration
  • deploying 42 onto different platforms
  • 42 and native code; how to import libraries from other languages
  • 42 optimizers