Author: Saim Khalid

  • History

    History of Java

    Java programming language was originally developed by Sun Microsystems which was initiated by James Gosling and released in 1995 as core component of Sun Microsystems’ Java platform (Java 1.0 [J2SE]). History of even naming of the Java is very interesting. It went under many names.

    Java Name History

    GreenTalk

    James Gosling was leading a team named as ‘Green’ team. Target of this team was to create a new project which can. Initially C++ was the original choice to develop the project. James Gosling wanted to enhance C++ to achieve the target but due to high memory usage, that idea was rejected and team started with a new language initially named as GreenTalk. The file extension used as .gt. Later this language was termed as Oak and finally to Java.

    Oak

    James Gosling renamed language to Oak. There was an Oak tree in front of his office. James Gosling used this name as Oak represents solidarity and Oak tree is the national tree of multiple countries like USA, France, Romania etc. But Oak technologies already had Oak as a trademark and James team had to brainstrom another title for the language.

    Finally Java

    Team put multiple names like DNA, Silk, Ruby and Java. Java was finalized by the team. James Gosling tabled Java title based on type of espresso coffee bean. Java is an island in Indonesia where new coffee was discovered termed as Java coffee. As per James Gosling, Java was among the top choice along with Silk. Finally Java was selected as it was quite unique and represented the essence of being dynamic,revolutionary and fun to say.

    Sun released the first public implementation as Java 1.0 in 1995. It promised Write Once, Run Anywhere (WORA), providing no-cost run-times on popular platforms.

    On 13 November, 2006, Sun released much of Java as free and open source software under the terms of the GNU General Public License (GPL).

    On 8 May, 2007, Sun finished the process, making all of Java’s core code free and open-source, aside from a small portion of code to which Sun did not hold the copyright.

    The latest release of the Java Standard Edition is Java SE 21. With the advancement of Java and its widespread popularity, multiple configurations were built to suit various types of platforms. For example: J2EE for Enterprise Applications, J2ME for Mobile Applications.

    Java Versions History

    Over the period of nearly 30 years, Java has seen many minor and major versions. Following is a brief explaination of versions of java till date.

    Sr.No.VersionDateDescription
    1JDK Beta1995Initial Draft version
    2JDK 1.023 Jan 1996A stable variant JDK 1.0.2 was termed as JDK 1
    3JDK 1.119 Feb 1997Major features like JavaBeans, RMI, JDBC, inner classes were added in this release.
    4JDK 1.28 Dec 1998Swing, JIT Compiler, Java Modules, Collections were introduced to JAVA and this release was a great success.
    5JDK 1.38 May 2000HotSpot JVM, JNDI, JPDA, JavaSound and support for Synthetic proxy classes were added.
    6JDK 1.46 Feb 2002Image I/O API to create/read JPEG/PNG image were added. Integrated XML parser and XSLT processor (JAXP) and Preferences API were other important updates.
    7JDK 1.5 or J2SE 530 Sep 2004Various new features were added to the language like foreach, var-args, generics etc.
    8JAVA SE 611 Dec 20061. notation was dropped to SE and upgrades done to JAXB 2.0, JSR 269 support and JDBC 4.0 support added.
    9JAVA SE 77 Jul 2011Support for dynamic languages added to JVM. Another enhancements included string in switch case, compressed 64 bit pointers etc.
    10JAVA SE 818 Mar 2014Support for functional programming added. Lambda expressions,streams, default methods, new date-time APIs introduced.
    11JAVA SE 921 Sep 2017Module system introduced which can be applied to JVM platform.
    12JAVA SE 1020 Mar 2018Unicode language-tag extensions added. Root certificates, threadlocal handshakes, support for heap allocation on alternate memory devices etc were introduced.
    13JAVA SE 115 Sep 2018Dynamic class-file constants,Epsilon a no-op garbage collector, local-variable support in lambda parameters, Low-overhead heap profiling support added.
    14JAVA SE 1219 Mar 2019Experimental Garbage Collector,Shenandoah: A Low-Pause-Time Garbage Collector, Microbenchmark Suite, JVM Constants API added.
    15JAVA SE 1317 Sep 2019Feature added – Text Blocks (Multiline strings), Enhanced Thread-local handshakes.
    16JAVA SE 1417 Mar 2020Feature added – Records, a new class type for modelling, Pattern Matching for instanceof, Intuitive NullPointerException handling.
    17JAVA SE 1515 Sep 2020Feature added – Sealed Classes, Hidden Classes, Foreign Function and Memory API (Incubator).
    18JAVA SE 1616 Mar 2021Feature added as preview – Records, Pattern Matching for switch, Unix Domain Socket Channel (Incubator) etc.
    19JAVA SE 1714 Sep 2021Feature added as finalized – Sealed Classes, Pattern Matching for instanceof, Strong encapsulation of JDK internals by default. New macOS rendering pipeline etc.
    20JAVA SE 1822 Mar 2022Feature added – UTF-8 by Default, Code Snippets in Java API Documentation, Vector API (Third incubator), Foreign Function, Memory API (Second Incubator) etc.
    21JAVA SE 1920 Sep 2022Feature added – Record pattern, Vector API (Fourth incubator), Structured Concurrency (Incubator) etc.
    22JAVA SE 2021 Mar 2023Feature added – Scoped Values (Incubator), Record Patterns (Second Preview), Pattern Matching for switch (Fourth Preview),Foreign Function & Memory API (Second Preview) etc.
    22JAVA SE 2119 Sep 2023Feature added – String Templates (Preview), Sequenced Collections, Generational ZGC, Record Patterns, Pattern Matching for switch etc.
  • Overview

    Java programming language was originally developed by Sun Microsystems which was initiated by James Gosling and released in 1995 as core component of Sun Microsystems’ Java platform (Java 1.0 [J2SE]).

    The latest release of the Java Standard Edition is Java SE 8. With the advancement of Java and its widespread popularity, multiple configurations were built to suit various types of platforms. For example: J2EE for Enterprise Applications, J2ME for Mobile Applications.

    The new J2 versions were renamed as Java SE, Java EE, and Java ME respectively. Java is guaranteed to be Write Once, Run Anywhere.

    Java is −

    • Object Oriented − In Java, everything is an Object. Java can be easily extended since it is based on the Object model.
    • Platform Independent − Unlike many other programming languages including C and C++, when Java is compiled, it is not compiled into platform specific machine, rather into platform independent byte code. This byte code is distributed over the web and interpreted by the Virtual Machine (JVM) on whichever platform it is being run on.
    • Simple − Java is designed to be easy to learn. If you understand the basic concept of OOP Java, it would be easy to master.
    • Secure − With Java’s secure feature it enables to develop virus-free, tamper-free systems. Authentication techniques are based on public-key encryption.
    • Architecture-neutral − Java compiler generates an architecture-neutral object file format, which makes the compiled code executable on many processors, with the presence of Java runtime system.
    • Portable − Being architecture-neutral and having no implementation dependent aspects of the specification makes Java portable. Compiler in Java is written in ANSI C with a clean portability boundary, which is a POSIX subset.
    • Robust − Java makes an effort to eliminate error prone situations by emphasizing mainly on compile time error checking and runtime checking.
    • Multithreaded − With Java’s multithreaded feature it is possible to write programs that can perform many tasks simultaneously. This design feature allows the developers to construct interactive applications that can run smoothly.
    • Interpreted − Java byte code is translated on the fly to native machine instructions and is not stored anywhere. The development process is more rapid and analytical since the linking is an incremental and light-weight process.
    • High Performance − With the use of Just-In-Time compilers, Java enables high performance.
    • Distributed − Java is designed for the distributed environment of the internet.
    • Dynamic − Java is considered to be more dynamic than C or C++ since it is designed to adapt to an evolving environment. Java programs can carry extensive amount of run-time information that can be used to verify and resolve accesses to objects on run-time.

    Hello World using Java Programming

    Just to give you a little excitement about Java programming, I’m going to give you a small conventional C Programming Hello World program, You can try it using Demo link.

    publicclassMyFirstJavaProgram{/* This is my first java program.
    
    * This will print 'Hello World' as the output
    */publicstaticvoidmain(String&#91;]args){System.out.println("Hello World");// prints Hello World}}</code></pre>

    History of Java

    James Gosling initiated Java language project in June 1991 for use in one of his many set-top box projects. The language, initially called 'Oak' after an oak tree that stood outside Gosling's office, also went by the name 'Green' and ended up later being renamed as Java, from a list of random words.

    Sun released the first public implementation as Java 1.0 in 1995. It promised Write Once, Run Anywhere (WORA), providing no-cost run-times on popular platforms.

    On 13 November, 2006, Sun released much of Java as free and open source software under the terms of the GNU General Public License (GPL).

    On 8 May, 2007, Sun finished the process, making all of Java's core code free and open-source, aside from a small portion of code to which Sun did not hold the copyright.

    Tools You Will Need

    For performing the examples discussed in this tutorial, you will need a Pentium 200-MHz computer with a minimum of 64 MB of RAM (128 MB of RAM recommended).

    You will also need the following softwares −

    • Linux 7.1 or Windows xp/7/8 operating system
    • Java JDK 8
    • Microsoft Notepad or any other text editor

    This tutorial will provide the necessary skills to create GUI, networking, and web applications using Java.

  • Environment Setup

    Setting up Fortran in Windows

    G95 is the GNU Fortran multi-architechtural compiler, used for setting up Fortran in Windows. The windows version emulates a unix environment using MingW under windows. The installer takes care of this and automatically adds g95 to the windows PATH variable.

    You can get the stable version of G95 from here

    installer setup
    mini installer setup

    AD

    https://delivery.adrecover.com/recover.html?siteId=18107&dataDogLoggingEnabled=false&dataDogLoggingVersion=1

    How to use G95

    During installation, g95 is automatically added to your PATH variable if you select the option “RECOMMENDED”. This means that you can simply open a new Command Prompt window and type “g95” to bring up the compiler. Find some basic commands below to get you started.

    Sr.NoCommand & Description
    1g95 –c hello.f90Compiles hello.f90 to an object file named hello.o
    2g95 hello.f90Compiles hello.f90 and links it to produce an executable a.out
    3g95 -c h1.f90 h2.f90 h3.f90Compiles multiple source files. If all goes well, object files h1.o, h2.o and h3.o are created
    4g95 -o hello h1.f90 h2.f90 h3.f90Compiles multiple source files and links them together to an executable file named ‘hello’

    Command line options for G95

    -c Compile only, do not run the linker.
    -o Specify the name of the output file, either an object file or the executable.
    

    Multiple source and object files can be specified at once. Fortran files are indicated by names ending in “.f”, “.F”, “.for”, “.FOR”, “.f90”, “.F90”, “.f95”, “.F95”, “.f03” and “.F03”. Multiple source files can be specified. Object files can be specified as well and will be linked to form an executable file.

  • Overview

    Fortran, as derived from Formula Translating System, is a general-purpose, imperative programming language. It is used for numeric and scientific computing.

    Fortran was originally developed by IBM in the 1950s for scientific and engineering applications. Fortran ruled this programming area for a long time and became very popular for high performance computing, because.

    It supports −

    • Numerical analysis and scientific computation
    • Structured programming
    • Array programming
    • Modular programming
    • Generic programming
    • High performance computing on supercomputers
    • Object oriented programming
    • Concurrent programming
    • Reasonable degree of portability between computer systems

    AD

    https://delivery.adrecover.com/recover.html?siteId=18107&dataDogLoggingEnabled=false&dataDogLoggingVersion=1

    Facts about Fortran

    • Fortran was created by a team, led by John Backus at IBM in 1957.
    • Initially the name used to be written in all capital, but current standards and implementations only require the first letter to be capital.
    • Fortran stands for FORmula TRANslator.
    • Originally developed for scientific calculations, it had very limited support for character strings and other structures needed for general purpose programming.
    • Later extensions and developments made it into a high level programming language with good degree of portability.
    • Original versions, Fortran I, II and III are considered obsolete now.
    • Oldest version still in use is Fortran IV, and Fortran 66.
    • Most commonly used versions today are : Fortran 77, Fortran 90, and Fortran 95.
    • Fortran 77 added strings as a distinct type.
    • Fortran 90 added various sorts of threading, and direct array processing.
  • HTML DOM

    Every webpage resides inside a browser window which can be considered as an object.

    Document object represents the HTML document that is displayed in that window. The Document object has various properties that refer to other objects which allow access to and modification of document content.

    The way a document content is accessed and modified is called the Document Object Model, or DOM. The Objects are organized in a hierarchy. This hierarchical structure applies to the organization of objects in a Web document.

    • Window − Top of the hierarchy. It is the outmost element of the object hierarchy.
    • Document − Each HTML document that gets loaded into a window becomes a document object. The document contains the contents of the page.
    • Elements − represent the content on a web page. Examples include the text boxes, page title etc.
    • Nodes − are often elements, but they can also be attributes, text, comments, and other DOM types.

    Here is a simple hierarchy of a few important DOM objects −

    HTML DOM

    Dart provides the dart:html library to manipulate objects and elements in the DOM. Console-based applications cannot use the dart:html library. To use the HTML library in the web applications, import dart:html −

    import 'dart:html';
    

    Moving on, we will discuss some DOM Operations in the next section.

    Finding DOM Elements

    The dart:html library provides the querySelector function to search for elements in the DOM.

    Element querySelector(String selectors);
    

    The querySelector() function returns the first element that matches the specified group of selectors. “selectors should be string using CSS selector syntax as given below

    var element1 = document.querySelector('.className'); 
    var element2 = document.querySelector('#id'); 
    

    Example: Manipulating DOM

    Follow the steps given below, in the Webstorm IDE −

    Step 1 − File NewProject → In the location, provide the project name as DemoWebApp.

    Demowebapp

    Step 1 − In the section “Generate sample content”, select SimpleWebApplication.

    Create

    It will create a sample project, DemoWebApp. There is a pubspec.yaml file containing the dependencies which need to be downloaded.

    name: 'DemoWebApp' 
    version: 0.0.1 
    description: An absolute bare-bones web app. 
    
    #author: Your Name <[email protected]> 
    #homepage: https://www.example.com  
    environment:   
       sdk: '>=1.0.0 <2.0.0'  
    dependencies:   
       browser: '>=0.10.0 <0.11.0'   dart_to_js_script_rewriter: '^1.0.1'  
    transformers: 
    - dart_to_js_script_rewriter 

    If you are connected to Web, then these will be downloaded automatically, else you can right-click on the pubspec.yaml and get dependencies.

    Pub Get Dependencies

    In the web folder, you will find three files: Index.html, main.dart, and style.css

    Index.html

    <!DOCTYPE html>   
    <html> 
       <head>     
    
      &lt;meta charset = "utf-8"&gt;     
      &lt;meta http-equiv = "X-UA-Compatible" content = "IE = edge"&gt;     
      &lt;meta name = "viewport" content = "width = device-width, initial-scale = 1.0"&gt;
      &lt;meta name = "scaffolded-by" content = "https://github.com/google/stagehand"&gt;
      &lt;title&gt;DemoWebApp&lt;/title&gt;     
      &lt;link rel = "stylesheet" href = "styles.css"&gt;     
      &lt;script defer src = "main.dart" type = "application/dart"&gt;&lt;/script&gt;
      &lt;script defer src = "packages/browser/dart.js"&gt;&lt;/script&gt; 
    </head> <body>
      &lt;h1&gt;
         &lt;div id = "output"&gt;&lt;/div&gt; 
      &lt;/h1&gt;  
    </body> </html>

    Main.dart

    import 'dart:html';  
    void main() {   
       querySelector('#output').text = 'Your Dart web dom app is running!!!.'; 
    } 

    Run the index.html file; you will see the following output on your screen.

    Demo Web App

    Event Handling

    The dart:html library provides the onClick event for DOM Elements. The syntax shows how an element could handle a stream of click events.

    querySelector('#Id').onClick.listen(eventHanlderFunction); 
    

    The querySelector() function returns the element from the given DOM and onClick.listen() will take an eventHandler method which will be invoked when a click event is raised. The syntax of eventHandler is given below −

    void eventHanlderFunction (MouseEvent event){ } 
    

    Let us now take an example to understand the concept of Event Handling in Dart.

    TestEvent.html

    <!DOCTYPE html> 
    <html> 
       <head> 
    
      &lt;meta charset = "utf-8"&gt; 
      &lt;meta http-equiv = "X-UA-Compatible" content = "IE = edge"&gt; 
      &lt;meta name = "viewport" content = "width = device-width, initial-scale = 1.0"&gt; 
      &lt;meta name = "scaffolded-by" content ="https://github.com/google/stagehand"&gt; 
      &lt;title&gt;DemoWebApp&lt;/title&gt; 
      &lt;link rel = "stylesheet" href = "styles.css"&gt; 
      &lt;script defer src = "TestEvent.dart" type="application/dart"&gt;&lt;/script&gt; 
      &lt;script defer src = "packages/browser/dart.js"&gt;&lt;/script&gt; 
    </head> <body>
      &lt;div id = "output"&gt;&lt;/div&gt; 
      &lt;h1&gt; 
         &lt;div&gt; 
            Enter you name : &lt;input type = "text" id = "txtName"&gt; 
            &lt;input type = "button" id = "btnWish" value="Wish"&gt; 
         &lt;/div&gt; 
      &lt;/h1&gt; 
      &lt;h2 id = "display"&gt;&lt;/h2&gt; 
    </body> </html>

    TestEvent.dart

    import 'dart:html'; 
    void main() { 
       querySelector('#btnWish').onClick.listen(wishHandler); 
    }  
    void wishHandler(MouseEvent event){ 
       String name = (querySelector('#txtName')  as InputElement).value; 
       querySelector('#display').text = 'Hello Mr.'+ name; 
    }

    Output

    Output
  • Unit Testing

    Unit Testing involves testing every individual unit of an application. It helps the developer to test small functionalities without running the entire complex application.

    The Dart external library named “test” provides a standard way of writing and running unit tests.

    Dart unit testing involves the following steps −

    Step 1: Installing the “test” package

    To installing third-party packages in the current project, you will require the pubspec.yaml file. To install test packages, first make the following entry in the pubspec.yaml file −

    dependencies: 
    test:
    

    After making the entry, right-click the pubspec.yaml file and get dependencies. It will install the “test” package. Given below is a screenshot for the same in the WebStorm Editor.

    Unit Testing

    Packages can be installed from the command line too. Type the following in the terminal −

    pub get
    

    Step 2: Importing the “test” package

    import "package:test/test.dart";
    

    Step 3 Writing Tests

    Tests are specified using the top-level function test(), while test assertions are made using the expect() function. For using these methods, they should be installed as a pub dependency.

    Syntax

    test("Description of the test ", () {  
       expect(actualValue , matchingValue) 
    });
    

    The group() function can be used to group tests. Each group’s description is added to the beginning of its test’s descriptions.

    Syntax

    group("some_Group_Name", () { 
       test("test_name_1", () { 
    
      expect(actual, equals(exptected)); 
    }); test("test_name_2", () {
      expect(actual, equals(expected)); 
    }); })

    Example 1: A Passing Test

    The following example defines a method Add(). This method takes two integer values and returns an integer representing the sum. To test this add() method −

    Step 1 − Import the test package as given below.

    Step 2 − Define the test using the test() function. Here, the test() function uses the expect() function to enforce an assertion.

    import 'package:test/test.dart';      
    // Import the test package 
    
    int Add(int x,int y)                  
    // Function to be tested { 
       return x+y; 
    }  
    void main() { 
       // Define the test 
       test("test to check add method",(){  
    
      // Arrange 
      var expected = 30; 
      
      // Act 
      var actual = Add(10,20); 
      
      // Asset 
      expect(actual,expected); 
    }); }

    It should produce the following output −

    00:00 +0: test to check add method 
    00:00 +1: All tests passed! 
    

    Example 2: A Failing Test

    The subtract() method defined below has a logical mistake. The following test verifies the same.

    import 'package:test/test.dart'; 
    int Add(int x,int y){ 
       return x+y; 
    }
    int Sub(int x,int y){ 
       return x-y-1; 
    }  
    void main(){ 
       test('test to check sub',(){ 
    
      var expected = 10;   
      // Arrange 
      
      var actual = Sub(30,20);  
      // Act 
      
      expect(actual,expected);  
      // Assert 
    }); test("test to check add method",(){
      var expected = 30;   
      // Arrange 
      
      var actual = Add(10,20);  
      // Act 
      
      expect(actual,expected);  
      // Asset 
    }); }

    Output − The test case for the function add() passes but the test for subtract() fails as shown below.

    00:00 +0: test to check sub 
    00:00 +0 -1: test to check sub 
    Expected: <10> 
    Actual: <9> 
    package:test  expect 
    bin\Test123.dart 18:5  main.<fn> 
       
    00:00 +0 -1: test to check add method 
    00:00 +1 -1: Some tests failed.  
    Unhandled exception: 
    Dummy exception to set exit code. 
    #0  _rootHandleUncaughtError.<anonymous closure> (dart:async/zone.dart:938) 
    #1  _microtaskLoop (dart:async/schedule_microtask.dart:41)
    #2  _startMicrotaskLoop (dart:async/schedule_microtask.dart:50) 
    #3  _Timer._runTimers (dart:isolate-patch/timer_impl.dart:394) 
    #4  _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414) 
    #5  _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148) 
    

    Grouping Test Cases

    You can group the test cases so that it adds more meaning to you test code. If you have many test cases this helps to write much cleaner code.

    In the given code, we are writing a test case for the split() function and the trim function. Hence, we logically group these test cases and call it String.

    Example

    import "package:test/test.dart"; 
    void main() { 
       group("String", () { 
    
      test("test on split() method of string class", () { 
         var string = "foo,bar,baz"; 
         expect(string.split(","), equals(&#91;"foo", "bar", "baz"])); 
      }); 
      test("test on trim() method of string class", () { 
         var string = "  foo "; 
         expect(string.trim(), equals("foo")); 
      }); 
    }); }

    Output − The output will append the group name for each test case as given below −

    00:00 +0: String test on split() method of string class 
    00:00 +1: String test on trim() method of string class 
    00:00 +2: All tests passed
    
  • Libraries

    Elixir provides excellent interoperability with Erlang libraries. Let us discuss a few libraries in brief.

    The Binary Module

    The built-in Elixir String module handles binaries that are UTF-8 encoded. The binary module is useful when you are dealing with binary data that is not necessarily UTF-8 encoded. Let us consider an example to further understand the Binary module −

    # UTF-8
    IO.puts(String.to_char_list("Ø"))
    
    # binary
    IO.puts(:binary.bin_to_list "Ø")

    When the above program is run, it produces the following result −

    [216]
    [195, 152]
    

    The above example shows the difference; the String module returns UTF-8 codepoints, while :binary deals with raw data bytes.

    The Crypto Module

    The crypto module contains hashing functions, digital signatures, encryption and more. This module is not part of the Erlang standard library, but is included with the Erlang distribution. This means you must list :crypto in your project’s applications list whenever you use it. Let us see an example using the crypto module −

    IO.puts(Base.encode16(:crypto.hash(:sha256, "Elixir")))

    When the above program is run, it produces the following result −

    3315715A7A3AD57428298676C5AE465DADA38D951BDFAC9348A8A31E9C7401CB
    

    The Digraph Module

    The digraph module contains functions for dealing with directed graphs built of vertices and edges. After constructing the graph, the algorithms in there will help finding, for instance, the shortest path between two vertices, or loops in the graph. Note that the functions in :digraph alter the graph structure indirectly as a side effect, while returning the added vertices or edges.

    digraph = :digraph.new()
    coords = [{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}]
    [v0, v1, v2] = (for c <- coords, do: :digraph.add_vertex(digraph, c))
    :digraph.add_edge(digraph, v0, v1)
    :digraph.add_edge(digraph, v1, v2)
    for point <- :digraph.get_short_path(digraph, v0, v2) do 
       {x, y} = point
       IO.puts("#{x}, #{y}")
    end

    When the above program is run, it produces the following result −

    0.0, 0.0
    1.0, 0.0
    1.0, 1.0
    

    The Math Module

    The math module contains common mathematical operations covering trigonometry, exponential and logarithmic functions. Let us consider the following example to understand how the Math module works −

    # Value of pi
    IO.puts(:math.pi())
    
    # Logarithm
    IO.puts(:math.log(7.694785265142018e23))
    
    # Exponentiation
    IO.puts(:math.exp(55.0))
    
    #...

    When the above program is run, it produces the following result −

    3.141592653589793
    55.0
    7.694785265142018e23
    

    The Queue Module

    The queue is a data structure that implements (double-ended) FIFO (first-in first-out) queues efficiently. The following example shows how a Queue module works −

    q = :queue.new
    q = :queue.in("A", q)
    q = :queue.in("B", q)
    {{:value, val}, q} = :queue.out(q)
    IO.puts(val)
    {{:value, val}, q} = :queue.out(q)
    IO.puts(val)

    When the above program is run, it produces the following result −

    A
    B
    
  • Concurrency

    Concurrency is the execution of several instruction sequences at the same time. It involves performing more than one task simultaneously.

    Dart uses Isolates as a tool for doing works in parallel. The dart:isolate package is Dart’s solution to taking single-threaded Dart code and allowing the application to make greater use of the hard-ware available.

    Isolates, as the name suggests, are isolated units of running code. The only way to send data between them is by passing messages, like the way you pass messages between the client and the server. An isolate helps the program to take advantage of multicore microprocessors out of the box.

    Example

    Let’s take an example to understand this concept better.

    import 'dart:isolate';  
    void foo(var message){ 
       print('execution from foo ... the message is :${message}'); 
    }  
    void main(){ 
       Isolate.spawn(foo,'Hello!!'); 
       Isolate.spawn(foo,'Greetings!!'); 
       Isolate.spawn(foo,'Welcome!!'); 
       
       print('execution from main1'); 
       print('execution from main2'); 
       print('execution from main3'); 
    }

    Here, the spawn method of the Isolate class facilitates running a function, foo, in parallel with the rest of our code. The spawn function takes two parameters −

    • the function to be spawned, and
    • an object that will be passed to the spawned function.

    In case there is no object to pass to the spawned function, it can be passed a NULL value.

    The two functions (foo and main) might not necessarily run in the same order each time. There is no guarantee as to when foo will be executing and when main() will be executing. The output will be different each time you run.

    Output 1

    execution from main1 
    execution from main2 
    execution from main3 
    execution from foo ... the message is :Hello!! 
    

    Output 2

    execution from main1 
    execution from main2 
    execution from main3 
    execution from foo ... the message is :Welcome!! 
    execution from foo ... the message is :Hello!! 
    execution from foo ... the message is :Greetings!! 
    

    From the outputs, we can conclude that the Dart code can spawn a new isolate from running code like the way Java or C# code can start a new thread.

    Isolates differ from threads in that an isolate has its own memory. There’s no way to share a variable between isolates—the only way to communicate between isolates is via message passing.

    Note − The above output will be different for different hardware and operating system configurations.

    Isolate v/s Future

    Doing complex computational work asynchronously is important to ensure responsiveness of applications. Dart Future is a mechanism for retrieving the value of an asynchronous task after it has completed, while Dart Isolates are a tool for abstracting parallelism and implementing it on a practical high-level basis.

  • Async

    An asynchronous operation executes in a thread, separate from the main application thread. When an application calls a method to perform an operation asynchronously, the application can continue executing while the asynchronous method performs its task.

    Example

    Let’s take an example to understand this concept. Here, the program accepts user input using the IO library.

    import 'dart:io'; 
    void main() { 
       print("Enter your name :");            
       
       // prompt for user input 
       String name = stdin.readLineSync();  
       
       // this is a synchronous method that reads user input 
       print("Hello Mr. ${name}"); 
       print("End of main"); 
    } 

    The readLineSync() is a synchronous method. This means that the execution of all instructions that follow the readLineSync() function call will be blocked till the readLineSync() method finishes execution.

    The stdin.readLineSync waits for input. It stops in its tracks and does not execute any further until it receives the user’s input.

    The above example will result in the following output −

    Enter your name :     
    Tom                   
    
    // reads user input  
    Hello Mr. Tom 
    End of main
    

    In computing, we say something is synchronous when it waits for an event to happen before continuing. A disadvantage in this approach is that if a part of the code takes too long to execute, the subsequent blocks, though unrelated, will be blocked from executing. Consider a webserver that must respond to multiple requests for a resource.

    A synchronous execution model will block every other user’s request till it finishes processing the current request. In such a case, like that of a web server, every request must be independent of the others. This means, the webserver should not wait for the current request to finish executing before it responds to request from other users.

    Simply put, it should accept requests from new users before necessarily completing the requests of previous users. This is termed as asynchronous. Asynchronous programming basically means no waiting or non-blocking programming model. The dart:async package facilitates implementing asynchronous programming blocks in a Dart script.

    Example

    The following example better illustrates the functioning of an asynchronous block.

    Step 1 − Create a contact.txt file as given below and save it in the data folder in the current project.

    1, Tom 
    2, John 
    3, Tim 
    4, Jane 
    

    Step 2 − Write a program which will read the file without blocking other parts of the application.

    import "dart:async"; 
    import "dart:io";  
    
    void main(){ 
       File file = new File( Directory.current.path+"\\data\\contact.txt"); 
       Future<String> f = file.readAsString();  
      
       // returns a futrue, this is Async method 
       f.then((data)=>print(data));  
       
       // once file is read , call back method is invoked  
       print("End of main");  
       // this get printed first, showing fileReading is non blocking or async 
    }

    The output of this program will be as follows −

    End of main 
    1, Tom 
    2, John 
    3, Tim 
    4, Jan
    

    The “end of main” executes first while the script continues reading the file. The Future class, part of dart:async, is used for getting the result of a computation after an asynchronous task has completed. This Future value is then used to do something after the computation finishes.

    Once the read operation is completed, the execution control is transferred within “then()”. This is because the reading operation can take more time and so it doesn’t want to block other part of program.

    Dart Future

    The Dart community defines a Future as “a means for getting a value sometime in the future.” Simply put, Future objects are a mechanism to represent values returned by an expression whose execution will complete at a later point in time. Several of Dart’s built-in classes return a Future when an asynchronous method is called.

    Dart is a single-threaded programming language. If any code blocks the thread of execution (for example, by waiting for a time-consuming operation or blocking on I/O), the program effectively freezes.

    Asynchronous operations let your program run without getting blocked. Dart uses Future objects to represent asynchronous operations.

  • Errors Handling

    Elixir has three error mechanisms: errors, throws and exits. Let us explore each mechanism in detail.

    Error

    Errors (or exceptions) are used when exceptional things happen in the code. A sample error can be retrieved by trying to add a number into a string −

    IO.puts(1 + "Hello")

    When the above program is run, it produces the following error −

    ** (ArithmeticError) bad argument in arithmetic expression
       :erlang.+(1, "Hello")
    

    This was a sample inbuilt error.

    Raising Errors

    We can raise errors using the raise functions. Let us consider an example to understand the same −

    #Runtime Error with just a message
    raise "oops"  # ** (RuntimeError) oops

    Other errors can be raised with raise/2 passing the error name and a list of keyword arguments

    #Other error type with a message
    raise ArgumentError, message: "invalid argument foo"

    You can also define your own errors and raise those. Consider the following example −

    defmodule MyError do
       defexception message: "default message"
    end
    
    raise MyError  # Raises error with default message
    raise MyError, message: "custom message"  # Raises error with custom message

    Rescuing Errors

    We do not want our programs to abruptly quit but rather the errors need to be handled carefully. For this we use error handling. We rescue errors using the try/rescue construct. Let us consider the following example to understand the same −

    err = try do
       raise "oops"
    rescue
       e in RuntimeError -> e
    end
    
    IO.puts(err.message)

    When the above program is run, it produces the following result −

    oops
    

    We have handled errors in the rescue statement using pattern matching. If we do not have any use of the error, and just want to use it for identification purposes, we can also use the form −

    err = try do
       1 + "Hello"
    rescue
       RuntimeError -> "You've got a runtime error!"
       ArithmeticError -> "You've got a Argument error!"
    end
    
    IO.puts(err)

    When running above program, it produces the following result −

    You've got a Argument error!
    

    NOTE − Most functions in the Elixir standard library are implemented twice, once returning tuples and the other time raising errors. For example, the File.read and the File.read! functions. The first one returned a tuple if the file was read successfully and if an error was encountered, this tuple was used to give the reason for the error. The second one raised an error if an error was encountered.

    If we use the first function approach, then we need to use case for pattern matching the error and take action according to that. In the second case, we use the try rescue approach for error prone code and handle errors accordingly.

    Throws

    In Elixir, a value can be thrown and later be caught. Throw and Catch are reserved for situations where it is not possible to retrieve a value unless by using throw and catch.

    The instances are quite uncommon in practice except when interfacing with libraries. For example, let us now assume that the Enum module did not provide any API for finding a value and that we needed to find the first multiple of 13 in a list of numbers −

    val = try do
       Enum.each 20..100, fn(x) ->
    
      if rem(x, 13) == 0, do: throw(x)
    end "Got nothing" catch x -> "Got #{x}" end IO.puts(val)

    When the above program is run, it produces the following result −

    Got 26
    

    Exit

    When a process dies of “natural causes” (for example, unhandled exceptions), it sends an exit signal. A process can also die by explicitly sending an exit signal. Let us consider the following example −

    spawn_link fn -> exit(1) end

    In the example above, the linked process died by sending an exit signal with value of 1. Note that exit can also be “caught” using try/catch. For example −

    val = try do
       exit "I am exiting"
    catch
       :exit, _ -> "not really"
    end
    
    IO.puts(val)

    When the above program is run, it produces the following result −

    not really
    

    After

    Sometimes it is necessary to ensure that a resource is cleaned up after some action that can potentially raise an error. The try/after construct allows you to do that. For example, we can open a file and use an after clause to close it–even if something goes wrong.

    {:ok, file} = File.open "sample", [:utf8, :write]
    try do
       IO.write file, "olá"
       raise "oops, something went wrong"
    after
       File.close(file)
    end

    When we run this program, it will give us an error. But the after statement will ensure that the file descriptor is closed upon any such event.