Building: No need with python?

Yes, building is needed with python.  but in one special case it can be hidden in the background. This page provides background on building, both with python and kotlin.

It can seem that python programs do not even need building, but the reality is some form of build needed with any program.  The good part of building in python, is building as you develop is so simple you don’t really notice.  The negative is if you later want to package up what you have developed, you may be confronted with one of a wide range of different builds options some of which can be quite complex.

Building Introduction Topics:

  • What is Building?
  • The Two Ways to Build: Environment vs Package Build
    1. Environment Build
    2. Package Build
  • Building in Python
  • Building in Kotlin
  • Conclusion: The different focus of Python and Kotlin

What is Building?

A Definition: Building is the process of putting in place all the components needed for a program, and proving the code with location information for each component.

The components are the resources needed by the program, such as program code for library functions, and images that may be used by the program.

Developing in python, it can seem like there is no such step as ‘building’.  Just type ‘python ‘ and python will do all that is required.  The reality is that this is an environment build approach, and during development any new libraries or other resources are added to the environment. So the steps to prepare the environment happen over time and can be forgotten. It is only when there is a need to run the program on computer other than the development computer, and all the environment install steps need to be repeated, that the environment build gets noticed.

Note also, that reliance on this approach limits the use of python.

In fact while this is true for the simplest way of running python, it is not always true.  That is because the simplest way of running python relies heavily on an ‘environment build’.

The Two Ways to Build

Environment Build vs Package Build

An environment build is where all the resources needed for the program are installed in the environment prior to running the program, enabling different programs to share the same resources.

By contrast, package build is where the resources for the program are packaged inside the program file, ensuring each program is self contained and independent.

1. Environment Build.

For an environment build, it the environment around the program that is built. An environment build means running the program on a new computer will require an ‘install’. The install can either be a series of steps to be followed manually, or there can be an install program to perform those steps.

The advantages of environment build are:

  • no need to re-install resources that have been previously installed in the environment another program(s)
  • during development, each new resource can be installed as required and independently, resulting in only one build for the complete development cycle, spread out over the entire development cycle

Disadvantages of environment build:

  • distribution of the application requires either a manual install process, or building of an installer which can be an additional development step
  • different applications may want different versions of resources to be present in the environment which may cause complex conflicts that are difficult to identify and/or resolve

 2. Package Build

A package build is where the components are combined in a single runnable ‘package’ file containing the components required by the program.

Advantages of package build:

  • distribution of the application can be as simple as just one file
  • each application contains its own components so no version conflicts can occur

java.jar files use a pure package build approach, which does require a build before every run, but means a fully portable self contained program is readily available without extra steps.

Building in Python

Building in python is very different for different uses of python.

Developer is the end user: One of the most common situations with python is the SEAAS developer, who is both the developer of the program and the end user of program. The resources needed by the program are installed as the program is built so there never seems to be a build at all.

Building for files mostly becomes installing python, then ensuring all the imports have all the packages those imports require installed. If the imports all work, the environment for the program has been built.  Once the environment is built, the program can easily be run without further steps.  The disadvantage of the this ‘build the environment’ approach is that for each new version of python the environment to satisfy the all python programs must be rebuilt, or alternatively a virtual environment approach must be adopted for development, and deployment can be problematic.

Web Server: Even if a web server is viewed by millions of people, the application only needs to be installed once per server, and it can be installed by the developer or other very skilled people.  Manual install of the environment for the python code, even if there are several steps, is entirely practical and is done by the developer.

Mobile Applications: Kivy is probably the best mobile framework for python, but like any other mobile app, Kivy apps, like all mobile apps, must be fully packaged.  Building a packaging is not part of standard python workflow, so the specifics of packaging kivy must be learnt and is quite is a complex and often fragile process.

Sharing with other friend/colleague Python Programmers (SEAAS): Simply send the source file, the other programmer probably already has python (probably the right version?) installed.

With simple python programs, there are no other ‘parts’, just python itself and just the one file.  As programs grow, there are imports, and then libraries to install to enable more imports. If the person installing knows pip install, they will quickly satisfy other requirements.  No build by the developer, manual environment build by the end user that is quite straightforward provided the end user can develop in python.

Sharing libraries and/or applications on PyPI: PyPI (or the “cheeseshop”) allows sharing open source python projects ready for simple installation into any computers python environment with a simple ‘pip install’.

Windows / MacOS applications: To distribute an application, to be installed and run by someone who need not know how to program in python, there are a variety of solutions. py2exe and pyinstaller and examples, and in each case the process is equivalent to a build that automates the install for regular users of the program.

Building in Kotlin

The bad new: There is always a build process.

The good news: There are build processes that work for all scenarios and are highly refined.

First, on that bad news.  Even the kotlin “hello world” program needs a build.  The ‘hello world’ program must call a print function, that has to be connected with the program code.  With python, the print function is in the standard library, which was installed in the python environment when python was installed so the developer needs no further build, unless that developer wants to send the program to a friend as a “helloexe” type file……. which would of course need a build.  However for “hello world” , having a “hello.exe” is not needed so you do not notice.

With kotlin, you are going to get the equivalent of “hello.exe”, so you there will be a build. The “hello” code must be built into a file together with the “print” function to be a complete program, and that requires a build.  All kotlin programs are made ready for installation on a computer, without first installing kotlin on any computer which will run the program.  Either as the “hello.exe” with kotlin native, “hello.jar” with the java version or “hello.js” to run in a browser.  Kotlin offers that choice (a level of choice not matched by python) but always requires a build.

Secondly, on the good news: The build is very simple. Because every developer is doing builds all the time, building is highly evolved.  Building can seem complex, because it is very flexible, and to learn all that can be done with build is still huge.  But to learn simple builds, equivalent to the examples for python given above is very easy.  The trap to avoid is the trap of trying to learn all that can be done with builds before getting started.

Conclusion: The different focus of kotlin and python.

Note: What applies here for python, also applies for many other ‘dynamic’ languages.

For someone writing programs for their own use, or for their colleagues who can also program in python, python provides a virtually ‘build free’ development cycle. Building can be virtually ignored.

For web servers, where millions can use the site build in python and installed just once, python also provides a close to a build free experience, and this time even for those who program as a profession.

For applications or mobile apps to be distributed for the mass market, and particularly apps/application by professionals to earn revenue, the build free experience is no longer available and building then can be complex and more difficult than with kotlin.

Python: With respect to building, python is at its best for programs written to be used by the developer and other programming colleagues, or for web servers or web services.

All kotlin programs require building. For “hello world” it can be so automatic you will not notice, but you will notice soon, even if only building programs for you own use.

However, the build systems available with kotlin are more consistent and more powerful. In fact, some notable large scale python projects like linkedin use kotlin ecosystem build systems. Despite the desirability of the kotlin approach, building in python is scattered that developers moving to kotlin can have their be the first ever exposure to build systems when using kotlin.  Note: in an ideal world, all python projects could use the same build system as other languages such as kotlin  (as is the case with linkedin).

There is a learning curve to building with kotlin, and that will be nice shallow curve if you keep it simple or a very steep curve if  try to learn the most advanced building possibilities at the start (when you don’t need them).

Kotlin: you can have one build system to build everything, including professional application, in place of the several different systems needed with python, and the power available is so compelling that advanced python users invest considerable resources to making the same system available with python.



Starting with gradle, creating a simple build.gradle

(note: proof edits pending)

Gradle a very well known building tool, originating in JVM world, but spreading to wider and wider use. A building tool is designed to automate workflows, particularly for building programs but in fact can automate any workflow iincluding building, linting, testing, pushing and much more to make your life easier. Sometimes it could be hard to grasp the concept even after reading the official documentation. This guide focuses on the basics and can enable having gradle up and running within a few minutes.

1. Gradle Introduction
2. A practical workflow for working with gradle
3. Add plugins
4. Configure the plugin
5. Add the dependencies of your project
6. Configure the project information
7. End

Continue reading “Starting with gradle, creating a simple build.gradle”

Gradle with Intellij: Using build.gradle

When first opening a kotlin project that has a gradle configuration, the following two messages should appear:

  1.  Configure gradle in project – DO NOT DO THIS!!!
  2. Import gradle project – ONLY DO THIS ONE ONLY

The trap is that the first suggestion modifies the file, and in fact our trials, this will normally break the build.gradle file.  If you have selected this, the only solution is to then undo those modifications made by IntelliJ and try again.

The import gradle may require setting the gradle home directory.  Set this to the location where you installed gradle. On a Mac, this is typically /usr/local/opt/gradle/libexec.


Gradle window (view/tool windows/gradle or gradle from right sidebar)


Note if the import gradle option action does not appear, check if the gradle window is already available, in which case import gradle has already taken place.  If not, try closing and reopening the project after checking that the build.gradle file is in the project root.

Once the import gradle is complete (it takes a while),  open the gradle window (view/tool windows/gradle or gradle in the right sidebar) and expand tasks/build and activate the ‘build‘ option under tasks/build.

It might be useful to then select the gradle build in the run debug toolbar (as shown below):


by clicking the dropdown, and selecting an option with the green gradle icon (as shown to the left of Unnamed above) before using the build build/build project or the run or debug symbols from the bar shown above.  Do not use either of these options before running.

Kotlin Limitations vs Python

social-media-failThis page will serve as repository of limitations found when attempting to move kotlin code to python code. Some limitations are a natural consequence of moving to static types, others are effectively inherited from Java.

The list here is based on placing those I find most significant at the top, and the further down the list the less significant.

base class parameter pass through


Kotlin, like python, allows for optional parameters, a feature not found in Java.  A consequence of this feature is that libraries with heavily used classes can over time evolve to have a large number of optional parameters in the most heavily used methods.  A larger number of parameters should only occur in code in a language that has optional parameters, as without the parameters being optional, every extra parameter  would introduce overhead on every call.  These methods with a large number of parameters are often frequently used methods, and the goal is that well chosen defaults will mean that most of these optional parameters are only provided in exceptional cases.  While a typical instance of the class may require only 2 or 3 parameters, while there may be as many as 20 to chose from.

To find examples, I simply thought: “what are the most widely used python packages I can think of?”.  The first three that occurred to me to check were sqlalchemy,  attr, and Django, and for each of these I looked for the most basic usage cases I could find. The first examples I found are:

  • sqlalchemy:   Table Class  20 optional parameters (see ‘parameters’)
  • attr: atrr.s() function – 9 optional parameters (see attr.s function)
  • Django: Field class – 22 optional parameters (see __init__)

While such a large number of parameters should not normally occur in Java due to lack of optional parameters, I think these example establish that the pattern is common in well regarded python packages.

The Problem.

Consider the Django Fieldclass . This class serves as a base class for several other classes, such as  TextField, TimeField, BinaryField etc.  To code examples like these cleanly, some type of language mechanism is needed which effectively achieves:  “include all fields from the base class constructor (or other method from the base class) as also parameters to this class unless specifically declared in this class“.

Python uses the *args,**kwargs system, which for several reasons is not an appropriate solution for kotlin, but is at least a solution.  There are some more elegant solutions possible for kotlin, and perhaps one will be added at a later time.

In Python the code for defining the BinaryField Class is as follows (not exact code for simplicity):

class BinaryField(Field):

    def __init__(self, *args, **kwargs):
        kwargs['editable'] = False
        super().__init__(*args, **kwargs)
        // other init code goes here

while in kotlin (slightly changed for name conventions and simplicity) the code becomes:

class BinaryField(
        verboseName:String?=null, name:String?=null, primaryKey:Boolean=false,
        maxLength:Int?=null, unique:Boolean=false, blank:Boolean=false,
        nulled:Boolean=false, dbIndex:Boolean=false, rel:String?=null,
        default:Any?=null, //editable:Boolean=true, - force 'false' for editable
        uniqueForYear:Int?=null, choices:String?=null, helpText:String="",
        dbColumn:Int?=null, dbTablespace:Int?=null, autoCreated:Boolean=false,
        validators:List<Any>?=null, errorMessages:String?=null
 ):Field(verboseName=verboseName, name=name, primaryKey=primaryKey,
        maxLength=maxLength, unique=unique, blank=blank, nulled=nulled,
        dbIndex=dbIndex, rel=rel, default=default, editable=false,
        serialize=serialize, uniqueForYear=uniqueForYear, choices=choices,
        helpText=helpText, dbColumn=dbColumn,
        dbTablespace=dbTablespace, autoCreated=autoCreated,
        validators=validators, errorMessages=errorMessages) {
  // class code here

Clearly, the call to the base constructor will be much shorter if not using named parameters, which is a choice, but in a list this long I would use named parameters.

The code (or almost identical code) will be repeated TextField, TimeField and the over 12 other fields that inherit from Field. Any update to the parameter list for the base Field class is tedious to say the least.

This is a case where kotlin requires boilerplate that is not required in python. What is needed is some way to say “accept all parameters to the base default constructor not specifically named in the base call, and pass these parameters through“. Given this problem will not occur in Java libraries which have no default parameters, it may be some time before kotlin designers consider this, if ever.  In the mean time, messy.

Constructor Calls

(to be added: by Nov 13)

Intricate, preset order, class data initialisation

Kotlin has what can appear a rather strange way of implementing the overriding of properties when extending classes.  The result is that when extending classes, the behaviour of initcode can be unexpected.  The way to avoid this is to use lazy properties in place of initialising during init.

open class Base{
    val simple = 3
    open val open = 3
    open val openGet = 3
    open val getter get()= 3
    open val getOpen get()= 3
    open val getDelg by GetDelg(3)
    init {
        println("base simple $simple open $open openG $openGet "+
                "getOpen $getOpen getter $getter "+
                " getDelg $getDelg")
    //open fun add(a:Int,b:Int) = a + b

class SubClass:Base(){
    override val open = 4
    override val openGet get()= 4
    override val getter get() = 4
    override val getOpen = 4
    //override val getDelg by GetDelg(4)  //uncomment for null pointer
    init {
        println("sub simple $simple open $open openG $openGet "+
                "getOpen $getOpen getter $getter "+
                " getDelg $getDelg")

class GetDelg(val value:Int){
    operator fun getValue(thisRef: Any?, property: KProperty<*>): Int {
        return value

The print from instancing a SubClass object is:

base simple 3 open 0 openG 4 getOpen 0 getter 4 getDelg 3
sub simple 3 open 4 openG 4 getOpen 4 getter 4 getDelg 3


Open is 0 in the base class init because the code to set the value has not yet been run, but not it is not 3 as you would expect.

openG, a value overridden by a get() method, perhaps unexpected returns the override value in both init() methods

getOpen, a get() method in the base overridden by a simple initialisation, behaves as a simple initialised value overridden by a new initialise, which is to be unitialised in the base init() method

getter() , a get() method overidden by another get() method returns the override value as does openG

getDelg() actually generates a null pointer exception if called during  the base init() method, as the overridden value has not been calculated

Note: part of this behaviour is base on the fact that overridden properties are actually new distinct properties, so the do not inherit values from base class property which is still accessible via super.<name>.  This means, counterintuitively, that open in the base init() method, returns 0while in the subclass init()will return 3

I will update with more on the use of lazy to avoid this issue, but the main point is to think carefully before initialising values in a base class that are open.

*args, **kwargs (to be added)

A specific use of *args and **kwargs has already been covered in base class parameter pass through.

Outside of that specific use, kotlin does have effective equivalents to most use cases, but may depend on the reflections library, which is not available on all platforms at this time.

vararg parameters capture the equivalent to a *args list, and allows for using the list for calling in a manner very similar to python.

callBy provide most of the functionality of **kwargs when used for calling functions, but some code is needed to map parameter names to KParameters.  A link to such code may be added to this page is someone asks 🙂

For cases where it is desired to capture parameters in map for, using a map actually makes better sense in every case I have found, but I will update this further if I find a case where this is not true.

Kotlin beyond Android: A risk?

Support for a language is dependant on the popularity of that language.  The only possible risk in choosing kotlin is the project becoming an orphan as kotlin never gains sufficient traction in the relevant space.  Choosing any language on the assumption that popularity will increase is a gamble,  so understanding the popularity of kotlin now and are the prospects for future popularity is essential in understanding the risk of future kotlin support.

Depending on the language popularity indicator you reference, kotlin is either climbing the rankings or already very near to top.  Kotlin on Android is widely tipped to overtake Java as the number 1 language, and choosing the number 1 language cannot really be considered a risk.  Could choosing Kotlin for development other than Android still be considered a risk, given the positive signs for kotlin uptake?

Continue reading “Kotlin beyond Android: A risk?”