I study Faculty of Information Technology at VUT in Brno and the main aim of my bachelor thesis is a research of developing the cross-platform desktop applications. The adult spends approximately 2.5 hours per day on desktop computers as shown by the statistics that took place between 2008 and 2015. While the time spent on mobile phones increases, the time spent on desktop computers is, on the other hand, not decreasing. In my opinion, this has a great potential in developing a single desktop application that can be run on all major operating systems. An application such as this that can be built via Electron framework.

Electron

It is an open-source framework that allows the creation of native desktop applications on Linux, Windows and macOS platforms with web technologies like JavaScript, HTML, and CSS. A combination of Chromium and Node.js makes this possible. The application that is created by Electron has all the benefits of a native desktop application, such as access to the file system or system notifications. It is recommended to use the npm package manager of Node.js while developing the application. With the npm, a developer can record the necessary modules during development into the package.json file, run the application itself, etc.

Processes

In the Electron application, there are two types of processes: the main process and the renderer process. Each one has its own unique role. The process that runs script specified in the package.json as the main one is called the main process. The main process runs renderer processes and takes care of communicating with the API of the operating system. It allows developing the application with OS’s native GUI. Each renderer process renders the content of one web page. The renderer process runs in isolation from other renderer processes.

Development basic application

To develop basic Electron application, it is necessary to create three files: firstly, package.json with information about the application. Secondly, JavaScript file which will be run as the first one and, lastly, HTML file for creating GUI of application (i.e. the web page). The folder-structure of basic application can look like:

app/
├── package.json
├── main.js
└── index.html

To run the application, you can download last Electron release from the web and copy app folder to the downloaded application as below and execute binary electron (electron.exe on Windows, etc.).

Folder-structure of Electron application on macOS

electron/Electron.app/Contents/Resources/
└── app/

Folder-structure of Electron application on Windows and Linux

electron/resources/
└── app/

Application distribution

After the application is developed, the developer can package the app folder into asar archive instead of distributing the app’s source code. In such a case, the app folder can be replaced, which includes the source code with app.asar package.

There are three options for distribution. The first one is to manually download all the latest versions of Electron for the necessary platforms and copy the application to the appropriate folder. Using the command line, a third-party tool Electron-packager creates also these packages. The second option, which includes creating install files, is to use the tools also from third parties: Electron-builder or Electron-windows-store.The last option, which includes distributing source code instead of package asar, is to use npm package manager.

The tool Electron-builder uses Electron-packager and creates the file needed to install the application. The format of the installer, that Electron-builder supports for Windows is NSIS. The most widely used packages for Linux are the deb, rpm, freebsd and apk. Similarly, for macOS there are dmg, pkg and mas. Electron-builder also supports automatic updates. If there are dependencies to the native operating system, compilation is required on this system. Otherwise, it is possible to compile application on a selected operating system or use some build server such as AppVeyor for Windows and Travis for Linux and macOS.

Other tool developed by Microsoft for compiling Electron applications into the .appx package is called Electron-windows-store. The tool is available from Microsoft PowerShell. Electron-windows-store can be used only in the operating system Windows 10 with Anniversary Update. Application format for windows store will be generated from the package of the Electron-packager tool. Requirements to compile application:

  • You must have a certificate that supports the application
  • The Windows 10 SDK
  • Node.js with a minimum version of 4.

The last option is to distribute only the source code and use the npm package manager to install dependencies and run the application. It is necessary to have all dependencies in the package.json file. Then, user just downloads the source code and executes these commands:

#to install all dependencies
$npm install
#to run application
$npm start

Coding some sequence processing in Clojure, I was wondering how efficient is the test for sequence emptiness. the first thing which comes in mind is:

 (when-not (empty? coll) …) 

Sometimes, this leads to unreadable code and for instance, Joy of Clojure recommends to simply use the following pun:

 (when (seq coll) …) 

So basically converting the collection into a sequence every time, leveraging the fact that empty sequence is nil, i.e. false.

The ancient C developer in me started screaming about the complexity of seq.

Well, let us see, what it really does:

(source seq)
(def ^{
   :arglists '(^clojure.lang.ISeq [coll])
   :doc "Returns a seq on the collection.
   If the collection is empty, returns nil.
   (seq nil) returns nil. seq also works
   on Strings, native Java arrays
   (of reference types) and any objects that
   implement Iterable."
   :tag clojure.lang.ISeq
   :added "1.0"<br>
   :static true}
   seq (fn ^:static seq ^clojure.lang.ISeq [coll]
     (. clojure.lang.RT (seq coll))))

As for many clojure.lang functions, it is simply a wrapper over a Java defined method. In this case, we are looking at Java class clojure.lang.RT.

Aside being almost a classbook example of lost type information and downcasting, this basically says that the performance depends heavily on the type of the collection we are trying to convert. For many cases, this is just a downcast – not a significant performance hit (we live in the Java world, right). For some, the conversion seems linear (have a look at the RT.seqFrom() method). So I have written two test functions to see how big hit the seq function is, when it comes to Java arrays for instance.


(defn hungry-sum1
([coll] (hungry-sum1 0 coll))
([s coll] (
if (seq coll)
(recur (+ s (first coll)) (rest coll))
s)))

(defn hungry-sum2
([coll] (hungry-sum2 0 coll))
([s coll] (
if (empty? coll) s
(recur (+ s (first coll)) (rest coll)))))

(def test-data
(into-array (range 1000000)))

(defn test1 []
(seq (repeatedly 1 #(hungry-sum1 test-data))))
(defn test2 []
(seq (repeatedly 1 #(hungry-sum2 test-data))))
(println "Testing with seq for emptiness.")
(time test1)
(println "Testing with empty? for emptiness.")
(time test2)

When you load this, to clojure REPL, you might get something like this:

user=> (load-file "seqloop.clj")
Testing with seq for emptiness.
"Elapsed time: 0.018768 msecs"
Testing with empty? for emptiness.
"Elapsed time: 0.01805 msecs"

Basically meaning the speed is the same. Well, definitely not something I would expect from this code.

Dig in:

(source empty?)
(defn empty?
  "Returns true if coll has no items -
   same as (not (seq coll)).
  Please use the idiom (seq x) rather
  than (not (empty? x))"
  {:added "1.0"
   :static true}
  [coll] (not (seq coll)))
nil

Surprise!!! Well, let’s just say that this is where i should have started in the first place :-//. I am going to play with this a bit and will get back, hopefully with some faster way how to test for collection emptiness. I am still not sure I like how Clojure treats sequences.

And yes, I know I should have read the documentation first ;-).

As our pet project me and my product management mates decided to improve the way we write user stories at Y Soft R&D department.

The biggest challenge is not to find what to do, as we are quite sure about that. The biggest challenge for us is to split to epic to user story in a useful way to be planned but still understandable way, so that developers see the value.

As the input user story, we took a story already posted here by our fellow Y Softer Ondra: I, as an End User, want the system to control access to my documents in a way visible to me, so that I can trust that my documents remain confidential.

This story is great as it represents the stakeholder value as well as the product vision. Our job is now to check whether the story is ready for development or if more backlog grooming is required.

We found the “How to split a user story” from Richard Lawrence (Agileforall.com) quite useful.

At our first session, we started with step 1 – INVEST model helping to prepare the input story. More information about INVEST can be found on wikipedia. The funny thing on INVEST model is that even if you split to small the story, the story must still satisfy the INVEST model. Therefore you have clear guidance on how far you can go with splitting.

So let’s go evaluate our story 🙂

Independent?

Yes.

Negotiable?

Yes, because the story is too high level. What’s negotiable: system (can be user), documents (can be control of something else), and value.

Valuable?

Yes, definitely

Estimable?

Partially, but not estimable to one sprint, since the output of the story can be everything from Human computer interaction to Biometric stuff.

Small?

No. Level of certainty is too low.

Testable?

No. It is very hard to find a metric for this story.

What does this mean?

The story is not done yet, so let’s continue to the next round and split the story!

In the next session we will try to split some more stories as well. 😉