Saturday, October 5, 2019

Webassembly Example C and C++ to HTML

Compiling C and C++ directly into a running web app is a thrill.

C Example

Save the following code to hello.c.
#include <stdio.h>
int main(int arg, char ** argv) {
  printf("Hello, world\n");
}
Note: point to the sdk! Run once after opening a terminal session, modifying the path to match your implementation.
$ source ~/dev/bin/emsdk/emsdk_env.sh --build=Release
Then, compile and run:
$ emcc hello.c -o hello.html
$ python -m SimpleHTTPServer 9000
open browser to http://localhost:9000/hello.html

C++ Example

Save the following code to dbldata.cpp.
#include <iostream>
struct Double_Data {
  Double_Data(const size_t size) : data(new double[size]) {}
  ~Double_Data() { delete [] data; }
  double *data;
};

Double_Data get_data() {
  Double_Data data(3);
  data.data[0] = 1.1; data.data[1] = 2.2; data.data[2] = 3.3;
  return data;
}

double sum_data(const Double_Data &d) {
  return d.data[0] + d.data[1] + d.data[2];
}

int main() {
  std::cout << sum_data(get_data()) << std::endl;
}
Note: point to the sdk! Run once after opening a terminal session, modifying the path to match your implementation.
$ source ~/dev/bin/emsdk/emsdk_env.sh --build=Release
Then, compile and run:
$ em++ dbldata.cpp -s -o dbldata.html
$ python -m SimpleHTTPServer 9000
open browser to http://localhost:9000/dbldata.html

C++ and Templates Example

Save the following code to dbldata.cpp.
#include <iostream>
template<typename Value_Type>
struct Data {
  Data(const size_t size) : data(new Value_Type[size]) {}
  ~Data() { delete [] data; }
  Value_Type *data;
};

template<typename Value_Type>
Data<Value_Type> get_data(const Value_Type &v1, 
                          const Value_Type &v2, 
                          const Value_Type &v3) {
  Data<Value_Type> d(3);
  d.data[0] = v1; d.data[1] = v2; d.data[2] = v3;
  return d;
}

template<typename Value_Type>
Value_Type sum_data(const Data<Value_Type> &d) {
  return d.data[0] + d.data[1] + d.data[2];
}

int main() {
  std::cout << sum_data(get_data(1.1, 3.3, 5.5)) << std::endl;
  std::cout << sum_data(get_data(11, 22, 33)) << std::endl;
}
Compile and run as before.

Running Example From bash Terminal

Verify the code is valid C++ by compiling and executing from the command line:
$ g++ dbldata.cpp -o dbldata
$ ./dbldata
9.9
66
The code in the C++ example was taken from Jason Turner's CppCon presentation "The Best Parts of C++"

Monday, June 17, 2019

How to Run Redis (note to self)

~ $ brew install redis ==> Downloading https://homebrew.bintray.com/bottles/redis-5.0.5.mojave.bottle.tar.gz ==> Downloading from https://akamai.bintray.com/eb/eb5538dadb10570c5a8aa9e8aafa5d21b7747e7597c92954916b9b6ca55 ######################################################################## 100.0% ==> Pouring redis-5.0.5.mojave.bottle.tar.gz ==> Caveats To have launchd start redis now and restart at login: brew services start redis Or, if you don't want/need a background service you can just run: redis-server /usr/local/etc/redis.conf ==> Summary 🍺 /usr/local/Cellar/redis/5.0.5: 13 files, 3.1MB ~ $

Sunday, June 9, 2019

Clojure's Java Interop With JDBC

Clojure's ability to interoperate with legacy Java is perhaps more often seen as a hurdle to be overcome rather than as a benefit. Clojure's syntax for executing native Java is different but a little practice can overcome that unfamiliarity.

Note: Clojure offers better means of utilizing JDBC than the Java interop I'm using in this code. I coded this example to show how to set up a project and how to code for Java interop rather than to advocate its use.

The syntax of a Clojure execution of a Java method is (. obj method). Here are examples showing various means of executing Java with Clojure:
(ns basic_interop.core
  (:import java.io.File java.util.Date java.util.Calendar))
(defn example [start end]
  (println start)
  (def dir (File. "/Users/gregh/.m2/repository"))
  (def path (.getAbsolutePath dir))
  (println path)
  (def date1 (Date.))
  (def date2 (new Date))
  (def date3 (.. Calendar getInstance getTime))
  (println (.getName (.getClass date1)) (.toString date1))
  (println (.. date3 getClass getName) (.toString date3))
  (println end))

(defn -main []
  (example "start..." "...end"))

Getting Clojure

To use Clojure on a laptop that didn't have Leiningen or Clojure, I simply did as instructed on https://leiningen.org/ and pasted the script copied from the leiningen web site into a file named lein that I saved in usr/local/bin folder and I then made the file executable.

Installing the Database

To perform the Clojure interaction with a database, I needed a database. I chose H2, the 'database in a jar'. The H2 database is simple to use and easy to setup. I downloaded the zip file containing the h2 database jar file from https://www.h2database.com and extracted the jar and ran it and, from the H2 console, ran the SQL to create the table:
create table Customers (id INT NOT NULL, cust_num INT NOT NULL,
first_name VARCHAR(64) NOT NULL, last_name VARCHAR(64) NOT NULL)


Creating the Clojure Project

Next, I ran lein new dbio to create the dbio project and cd dbio and then, to test the skeleton project, I ran lein run.

I modified the project.clj and the core.clj files as shown below.
(defproject dbio "0.1.0-SNAPSHOT"
  :description ""
  :url "http://"
  :license {:name "none"
            :url "https://"}
  :dependencies [[org.clojure/clojure "1.10.0"]
                 [com.h2database/h2 "1.4.199"]]
  :main dbio.core
  :repl-options {:init-ns dbio.core})
(ns dbio.core
  (:gen-class)
  (:import org.h2.tools.Server 
      (java.sql Connection DriverManager Statement 
       SQLException ResultSet ResultSetMetaData)))

(defn foo
  [speaker]
  (println speaker " says \"Hello, World!\""))

(defn doJdbc []

  (def conn (DriverManager/getConnection "jdbc:h2:~/test", "sa", ""))

  (def stmt (.createStatement conn))

  (.executeUpdate stmt "DELETE Customers")

  (.executeUpdate stmt 
    "INSERT INTO Customers VALUES (1, 1001, 'Homer', 'Simpson')")

  (.executeUpdate stmt 
    "INSERT INTO Customers VALUES (2, 1002, 'Bart', 'Simpson')")

  (def rs (.executeQuery stmt "SELECT * FROM Customers"))

  (while (.next rs)
    (println (.getString rs 3))))

(defn -main []
  (foo "Greg")
  (doJdbc))


Running the Clojure

Executing the command in a bash terminal lein run I got the following output:

Saturday, May 18, 2019

Getting Started With Kotlin

On the Kotlin download page, the native and experimental downloads versions of Kotlin for Windows, Mac and Unix do not work with the JVM. The JVM compatible version is simply "kotlin-compiler-1.3.31.zip".



Kotlin can be installed using Choco on Windows, Homebrew on Mac and wget on Unix. I chose to download it and so, after extracting the files, I had to add the kotlin/bin folder to the PATH on my machine. Java is, of course, prerequisite.

From the command line, entering kotlinc starts the REPL.

C:\>kotlinc
Welcome to Kotlin version 1.3.31 (JRE 1.8.0_191-b12)
Type :help for help, :quit for quit
>>> fun greet(name: String, greeting: String = "Howdy"): String = "\n$greeting $name"
fun greet(name: String, greeting: String = "Howdy")>>>
>>> println(greet("Greg"))
println(greet("Greg"))
Howdy Greg
>>> println(greet("Sue", "Bonjour"))
println(greet("Sue", "Bonjour"))
Bonjour Sue
>>> :quit

C:\>

Sunday, May 12, 2019

Lombok Example

Lombok can
• generate the getter and setter boilerplate
• perform null-checking
• provide var and val type inference to Java versions prior to Java 10
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>r4j-example</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  
  <dependencies>
      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.18.8</version>
          <scope>provided</scope>
      </dependency>
  </dependencies>
</project>
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

@Getter @Setter 
public class Account {
    String type;
    public Account() {}
}
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

@Getter @Setter 
public class Employee {
    String name;
    public Employee() {}
}
import java.util.HashMap;
import lombok.val;
import lombok.NonNull;

public class Example {
 Account account = new Account();
 Employee employee = new Employee();
 
    public HashMap valDemo() {
        val valMap = new HashMap();
        valMap.put(0, "zero");
        valMap.put(5, "five");
        valMap.put(30, "thirty");
        return valMap;
    }

    public void notNullDemo(@NonNull Employee employee, @NonNull Account account){
        employee.setName("Stephen");
        account.setType("Super-Saver");
    }
 
    public static void main(String[] args) {
        Example ex = new Example();
        System.out.println(ex.valDemo());
        ex.notNullDemo(ex.employee, ex.account);
  }
}

Thursday, May 9, 2019

Resilience for Java Example

There are some good explanations of Resilience4J (see https://dzone.com/articles/resilience4j-intro and https://www.baeldung.com/resilience4j) but, my initial interest is in getting a simple example running. Here is my maven pom and simple Java class and the results.
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>r4j-example</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  
  <dependencies>
    <dependency>
      <groupId>io.github.resilience4j</groupId>
      <artifactId>resilience4j-circuitbreaker</artifactId>
      <version>0.12.1</version>
    </dependency>
    <dependency>
      <groupId>io.github.resilience4j</groupId>
      <artifactId>resilience4j-rxjava2</artifactId>
      <version>0.13.1</version>
    </dependency>
    <dependency>
      <groupId>io.vavr</groupId>
      <artifactId>vavr</artifactId>
      <version>0.10.0</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
import io.github.resilience4j.circuitbreaker.*;
import io.github.resilience4j.circuitbreaker.event.CircuitBreakerEvent;
import io.github.resilience4j.circuitbreaker.event.CircuitBreakerOnStateTransitionEvent;
import io.github.resilience4j.circuitbreaker.internal.CircuitBreakerStateMachine;
import io.vavr.control.Try;

public class R4jExample {

  public static void main(String[] args) {
    CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.ofDefaults();

    CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker("example");

    // employ io.vavr.control.Try 
    Try result = Try.of(CircuitBreaker
      .decorateCheckedSupplier(circuitBreaker, () -> "Hello")
    ).map(value -> value + " world");

    System.out.println("this is it: " + result);

    Try result2 = Try.of(CircuitBreaker
      .decorateCheckedSupplier(circuitBreaker, () -> {
          throw new RuntimeException("BAM!");
      }));

    System.out.println("this is another: " + result2);

    Try result3 = Try.of(CircuitBreaker
      .decorateCheckedSupplier(circuitBreaker, () -> {
          throw new RuntimeException("BAM!");
      }));

    System.out.println("this is another: " + result3.getOrElse("Nothing"));
  }
}

Sunday, April 21, 2019

Chapter 1 Elixir

Run the command mix new counter and in the folder counter\lib, edit counter.ex.
defmodule Counter.Core do

  def inc(value) do
    value + 1
  end
end

defmodule Clock do
  def start(f) do
    run(f, 0)
  end

  def run(endless, count) do
    endless.(count)
    new_count = Counter.Core.inc(count)
    :timer.sleep(1000)
    run(endless, new_count)
  end
end


Chapter 2 Elixir

defmodule Counter.Core do

  def inc(value) do
    value + 1
  end
end

defmodule Counter.Server do
  def run(count) do
    new_count = listen(count)
    run(new_count)
  end

  def listen(count) do
    receive do
      {:tick, _pid} ->
        Counter.Core.inc(count)
      {:state, pid} ->
        send(pid, {:count, count})
        count
    end
  end
end

defmodule Counter do
  def start(initial_count) do
    spawn( fn() -> Counter.Server.run(initial_count) end)
  end
  def tick(pid) do
    send pid, {:tick, self()}
  end
  def state(pid) do
    send pid, {:state, self()}
    receive do
      {:count, value} -> value
    end
  end
end


Chapter 3 Elixir

Add test file counter_test.exs to the test folder
defmodule CounterTest do
  use ExUnit.Case
  test "inc increments an integer value" do
    assert Counter.Core.inc(1) == 2
  end
end
Add test file counter_api_test.exs to the test folder
defmodule CounterApiTest do
  use ExUnit.Case
  test "use counter through API" do
    pid = Counter.start(0)
    assert Counter.state(pid) == 0
  
    Counter.tick(pid)
    Counter.tick(pid)
  
    count = Counter.state(pid)
    assert count == 2
  end
end


Chapter 4 Elixir

Create folder simple_elixir and in it create file hello.exs
IO.puts "hello world"


Chapter 5 Elixir

run mix new pmap and edit pmap\lib\pmap.ex
defmodule Parallel do
  def pmap(collection, func) do
    collection 
 |> Enum.map(&(Task.async(fn -> func.(&1) 
 end)))
 |> Enum.map(&Task.await/1)
 
  end
end


Chapter 6 Elixir

Investigate functions using h(), the help function.

Chapter 7 Elixir

Investigate concurrency. Run mix new add_example and edit add_example/lib/add_example.ex
defmodule Add_Example do
  def add(a, b) do
    IO.puts(a + b)
  end
end
Run iex -S mix then enter the following two commands at the prompt to first make a blocking call then an asynchronous call.

Modify the code to process the response from the asynchronous call.
defmodule Add_Example do
  def listen do
    receive do
      {:ok, "hello"} -> IO.puts("World")
    end
    listen
  end
end


Tuples and Lists

iex(15)> coins = [{"penny", 1}, {"nickel", 5}]
[{"penny", 1}, {"nickel", 5}]

iex(16)> coins = coins ++ [{"dime", 10}]
[{"penny", 1}, {"nickel", 5}, {"dime", 10}]

iex(17)> coins = coins ++ [{"quarter", 25}]
[{"penny", 1}, {"nickel", 5}, {"dime", 10}, {"quarter", 25}]

iex(18)> coins = [penny: 1, nickel: 5, dime: 10, quarter: 25]
[penny: 1, nickel: 5, dime: 10, quarter: 25]
 
iex(19)> Keyword.get(change, :dime)
10
 
iex(20)> change[:nickel]
5
 
iex(21)> change = [penny: 1] ++ [nickel: 5] ++ [dime: 10]
[penny: 1, nickel: 5, dime: 10]
 
iex(22)> pocket_change = [{"penny", 1}] ++ [{"nickel", 5}] ++ [{"dime", 10}]
[{"penny", 1}, {"nickel", 5}, {"dime", 10}]
 
iex(23)> {name, age} = {"Bob", 25}
{"Bob", 25}
 
iex(24)> bob = {name, age}
{"Bob", 25}

iex(25)> {date, time} = :calendar.local_time
{{2019, 4, 30}, {22, 22, 24}}

iex(26)> {_, {hours, minutes, _}} = :calendar.local_time
{{2019, 4, 30}, {22, 28, 6}}

iex(27)> [head | tail] = [1, 2, 3, 4]
[1, 2, 3, 4]

iex(28)> head
1

iex(29)> tail
[2, 3, 4]

iex(30)> [head1 | [head2 | tail]] = [1, 2, 3, 4]
[1, 2, 3, 4]

iex(31)> head1
1

iex(32)> head2
2

iex(33)> 


Simple Functions

defmodule Splitter do
  def comma_split(str_quote) do
    str_quote |> String.split(",")
  end
  
  def letter_split(str_quote) do
    str_quote |> String.codepoints
  end
end


Overloaded Functions

defmodule Geo do 
  def how_big({:circle, radius}) do 
    radius * radius * 3.14 
  end
  
  def how_big({:rectangle, {l, w}}) do 
    l * w 
  end
end

iex(1)> Geo.how_big({:circle, 5})
78.5
iex(2)> Geo.how_big({:rectangle, {4, 5}})
20
iex(3)>


Equality

To avoid reassigning values to the variable, I move the variable to the RHS of the expression.
iex(1)> k9 = %{dog1: "dog", fox1: "fox"}
%{dog1: "dog", fox1: "fox"}

iex(2)> %{dog1: "dog", fox1: "fox"} = k9
%{dog1: "dog", fox1: "fox"}

iex(3)> %{dog1: "dog", fox1: "cat"} = k9
** (MatchError) no match of right hand side value: %{dog1: "dog", fox1: "fox"}

iex(4)>


Recursive Functions

defmodule Lists do
  def map([], _func), do: []
  def map([h | t], func), do: [func.(h) | map(t, func)]
end

iex(1)> Lists.map([], fn x -> 3 * x end)
[]
iex(2)> Lists.map([2,4,6], fn x -> 3 * x end)
[6, 12, 18]

Thursday, October 25, 2018

Gatsby 2.0

I'm performing the Gatsby tutorial from egghead.io. Gatsby is a command line tool that can generate a React web site that uses GraphQL.
$ gatsby new my-blog https://github.com/gatsbyjs/gatsby-starter-hello-world
$ cd my-blog
$ yarn
$ open http://localhost:8000/
$ gatsby develop
Note: after the gatsby develop command completes, hit refresh on the open web page to view server output. You will see Hello World! displayed in the browser.
$ npm install --save gatsby-sourcefilesystem@next gatsby-transformer-remark@next
$ touch gatsby-config.js && vi gatsby-config.js
blah... blah... blah...
$ open http://localhost:8000/___graphql
$ gatsby develop
Note: after the gatsby develop command completes, hit refresh on the open web page to view server output.

Thursday, October 18, 2018

Scheme and Kawa Lisps

I've run some exercises in the interpreter that I downloaded from www.scheme.com


> '(a b c d)
'(a b c d)
> (cons 'a '(b c))
'(a b c)
> (* 5 5)
25
> (define quadruple (lambda (n) (+ n n n n)))
> (quadruple 7)
28
> (cons 'a '(b c))
'(a b c)
> (car (cons 'x '(y z)))
'x
> (define doubler (lambda (f) (lambda (x) (f x x))))
> (define double (doubler +))
> (double 13/2)
13
> (define recip (lambda (n) (and (not (= n 0)) (/ 1 n))))
> (recip 4)
1/4
> (recip 3)
1/3
> (recip 0)
#f
> (define x1 '(one two three))
> (cons 'zero x1)
'(zero one two three)
> (define x2 (cons 'zero x1))
> (cdr x2)
'(one two three)
> (car x2)
'zero

And Kawa which is Scheme implemented on the JVM.

Code saved in First.scm file:
(display (< 7 9))
(newline)
(display (+ 7 11))
(newline)
Run command:
$ java -jar lib/kawa.jar ../src/First.scm
#t
18

Wednesday, October 17, 2018

Cargo Commands for Rust Build

$ cargo new project
$ cd project $ vi Cargo.toml -------------------------------- [package] name = "project" version = "0.1.0" authors = ["you "] [dependencies] dependency = "0.1" -------------------------------- $ cargo install dependency $ cargo build $ cargo run

Install & Connect to MySQL

$ brew install mysql
==> Downloading https://homebrew.bintray.com/bottles/mysql-8.0.12.mojave.bottle.tar.gz
######################################################################## 100.0%
==> Pouring mysql-8.0.12.mojave.bottle.tar.gz
==> Caveats
We've installed your MySQL database without a root password. To secure it run:
    mysql_secure_installation

MySQL is configured to only allow connections from localhost by default

To connect run:
    mysql -uroot

To have launchd start mysql now and restart at login:
  brew services start mysql
Or, if you don't want/need a background service you can just run:
  mysql.server start
==> Summary
🍺  /usr/local/Cellar/mysql/8.0.12: 255 files, 233.0MB
$ mysql_secure_installation

Monday, September 10, 2018

Clojure + Java Interop + JDBC

user=> (import '(java.sql Connection DriverManager Statement SQLException ResultSet
    ResultSetMetaData)) java.sql.ResultSetMetaData user=> (Class/forName "org.hsqldb.jdbc.JDBCDriver") org.hsqldb.jdbc.JDBCDriver user=> (def conn (DriverManager/getConnection
    "jdbc:hsqldb:hsql://localhost/clojuredb", "SA", "")) #'user/conn user=> (def stmt (.createStatement conn)) #'user/stmt user=> (def rs (.executeQuery stmt "SELECT * FROM Authors")) #'user/rs user=> (.next rs) true user=> (.getInt rs 1) 0 user=> (.getString rs 2) "Kurt" user=> (.getString rs 3) "Vonnegutt" user=>

Clojure Sorted Map

user=> (def stooges (sorted-map :a 'larry :b 'mo :c 'curly))
#'user/stooges
user=> (stooges :a)                                         
larry

Clojure with java.io.File

user=> (new File "temp.clj")
java.lang.IllegalArgumentException: Unable to resolve classname: File (NO_SOURCE_FILE:61)
user=> (import 'java.io.File)
java.io.File
user=> (new File "temp.clj") 
#

Start Clojure

cd dev/lib/clojure-1.1.0
java -cp .:clojure.jar:jline-0.9.94.jar jline.ConsoleRunner clojure.main

Start Clojure with HSQL jar

$ java -cp .:clojure.jar:jline-0.9.94.jar:../hsqldb/lib/hsqldb.jar
    jline.ConsoleRunner clojure.main

Friday, August 17, 2018

Data Structures with Clojure

user=> (defrecord Person [fname lname address])
user.Person
user=> (def greg (Person. "Greg" "Helton" "Texas"))
#'user/greg
user=> (def bill (Person. "Bill" "Gates" "Seattle"))
#'user/bill
user=> (def team '(bill greg))
#'user/team
user=> (nth team 1)
greg
user=> (:lname greg)
"Helton"
user=> (defrecord Languages [^String lang1 ^String lang2 ^String lang3])
user.Languages
user=> (defrecord Pgmr [^String fname ^String lname ^Languages languages]) 
user.Pgmr
user=> (def rich ["Rich" "Hickey" ["Clojure" "C++" "Lisp"]])
#'user/rich
user=> (println rich)
[Rich Hickey [Clojure C++ Lisp]]
nil

Decimal Math

user=> (+ 1 (+ 5 7))
13
user=> (+ 1 0.98M)
1.98M
user=> (+ 1 0.98M 0.97M 0.96M 0.95M)
4.86M

Sunday, March 25, 2018

JShell and Optional

jshell> List<String> people = List.of("Bill", "Sue", "Jenny", "Sarah", "Tim", "Brian");
people ==> [Bill, Sue, Jenny, Sarah, Tim, Brian]

jshell> people.stream().filter(p -> p.substring(0,1).equals("B"))
    .forEach(System.out::println) Bill Brian jshell> List<String> results = people.stream(). ...> filter(p -> p.substring(0,1).equals("B")). ...> collect(Collectors.toList()) results ==> [Bill, Brian] jshell> Optional<String> s = people.stream(). ...> filter(p -> p.startsWith("T")). ...> findFirst() s ==> Optional[Tim] jshell> Optional<String> s = people.stream(). ...> filter(p -> p.startsWith("W")). ...> findFirst() s ==> Optional.empty jshell> System.out.println(s.orElse("not found")) not found jshell>

Friday, March 23, 2018

JShell, Collectors, Stream, stream, map, filter and forEach

jshell> String[] names = {"Bill", "Sue", "Joey", "Samantha", "Theresa"};
names ==> String[5] { "Bill", "Sue", "Joey", "Samantha", "Theresa" }

jshell> Stream.of(names).forEach(p -> System.out.println(p.toUpperCase()))
BILL
SUE
JOEY
SAMANTHA
THERESA

jshell> 
jshell> List<String> people = List.of("Bill", "Sue", "Joey", "Samantha", "Theresa");
people ==> [Bill, Sue, Joey, Samantha, Theresa]

jshell> people.stream().map(String::toUpperCase).forEach(System.out::println)
BILL
SUE
JOEY
SAMANTHA
THERESA

jshell> people.stream().filter(p -> p.equals("Joey")).forEach(System.out::println)
Joey

jshell> 
jshell> List<String> people = List.of("Bill", "Sue", "Jenny", "Sarah", "Tim", "Brian");
people ==> [Bill, Sue, Jenny, Sarah, Tim, Brian]

jshell> people.stream().filter(p -> p.substring(0,1).equals("B"))
    .forEach(System.out::println) Bill Brian jshell> List<String> results = people.stream(). ...> filter(p -> p.substring(0,1).equals("B")). ...> collect(Collectors.toList()) results ==> [Bill, Brian] jshell>

Saturday, December 30, 2017

Mac & Chrome Shortcuts

Tired of reaching for the mouse all the time? Me too so I researched & found some shortcuts.

•  Apple t opens a new tab

•  Apple w closes the current tab

•  Apple 1 thru Apple 8 displays that # tab in the current window

•  Apple 9 displays the final tab

•  Apple h hides the current app

•  Apple TAB (below 1 key) toggle between apps

•  Apple ~ (above TAB key) toggle between windows within an app

•  Apple q to quit the app

•  Apple l (lower case L) positions the focus into the address bar

•  Apple + zoom in

•  Apple - zoom out

•  Apple 0 reset the zoom

•  Apple Alt/Option j opens the javascript console of the Developer Tools Repeat to close.

•  delete key ... In previous versions of Chrome the delete key would function like clicking the back arrow in the browser. Now you have to add the "Backspace to go Back" Chrome plugin to have this functionality work.

Terminal Commands

•  open <folder name> opens folder in Finder

•  open -a textedit pgm.cpp opens the file in the text editor

•  mkdir -p dir1/dir2 makes both folders because of -p option

Thursday, November 30, 2017

Using Maven Without a Repo & A Little Java 9 JShell

Let's use Maven to download some jars to the local folder (ie, not the user's .m2 repo).

The pom.xml File
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mystuff</groupId>
  <artifactId>rx</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

  <dependencies>

    <dependency>
      <groupId>io.reactivex.rxjava2</groupId>
      <artifactId>rxjava</artifactId>
      <version>2.1.7</version>
    </dependency>

  </dependencies>
</project>

The Command To Process the pom.xml File
$ mvn dependency:copy-dependencies -DoutputDirectory=lib

This results in downloading rxjava-2.1.7.jar and its dependency, reactive-streams-1.0.1.jar into the lib folder.

Let's Use These Jars in JShell
$ jenv local 9.0
$ jshell --class-path lib/reactive-streams-1.0.1.jar:lib/rxjava-2.1.7.jar
|  Welcome to JShell -- Version 9.0.1
|  For an introduction type: /help intro

jshell>  import io.reactivex.*;

jshell> public class HelloWorld {
   ...>   public static void main(String[] args) {
   ...>     Flowable.just("Hello World").subscribe(System.out::println);
   ...>   }
   ...> }
|  created class HelloWorld

jshell> String[] emptyArray = new String[0];
emptyArray ==> String[0] {  }

jshell> HelloWorld.main(emptyArray);
Hello World

jshell> import io.reactivex.functions.Consumer;

jshell> Flowable.just("Hello World").
   ...> subscribe(new Consumer() {
   ...> @Override public void accept(String s) {
   ...> System.out.println(s);
   ...> }
   ...> });
Hello World
$6 ==> CANCELLED

jshell> 

Monday, November 20, 2017

Java 9 jshell

I first downloaded and installed Java 9 and added it and Java 8 to jenv.
~ $ jenv add /Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home
oracle64-1.8.0.152 added
1.8.0.152 added
1.8 added
~ $ jenv versions
* system (set by /Users/gMac/.jenv/version)
  1.8
  1.8.0.152
  oracle64-1.8.0.152
~ $ jenv add /Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home
oracle64-9.0.1 added
9.0.1 added
9.0 added
~ $ jenv versions
* system (set by /Users/gMac/.jenv/version)
  1.8
  1.8.0.152
  9.0
  9.0.1
  oracle64-1.8.0.152
  oracle64-9.0.1
~ $ jenv local 1.8
~ $ java -version
java version "1.8.0_152"
Java(TM) SE Runtime Environment (build 1.8.0_152-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)
~ $ jenv local 9.0
~ $ java -version
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
~ $ jshell
|  Welcome to JShell -- Version 9.0.1
|  For an introduction type: /help intro

jshell> Math.PI
$1 ==> 3.141592653589793

jshell> 1 + $1
$2 ==> 4.141592653589793

jshell> IntStream.iterate(0, i -> i<100, i -> ++i).forEach(System.out::println)
01234567891011121314151617181920212223242526272829303132333435363738394041424344
45464748495051525354555657585960616263646566676869707172737475767778798081828384
858687888990919293949596979899

Sunday, November 5, 2017

Install MySQL with Homebrew and Create Spring JPA Application

Install MySQL and run a script file to create and populate the database.
$ brew install mysql
$ brew tap homebrew/services
$ brew services start mysql
$ mysqladmin -u root password 'secret'
$ mysql -u root -p
Enter password: ******
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.20
mysql> source ~/dev/src/mysql/bookstore.sql
mysql> use bookstore;
mysql> alter table books add column createdAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
mysql> alter table books add column updatedAt TIMESTAMP NULL ON UPDATE NOW();
mysql> quit
Bye
$
Create your Maven project by running the following command.
$ mvn -B archetype:generate /
 -DarchetypeGroupId=org.apache.maven.archetypes /
 -DgroupId=com.bookstore /
 -DartifactId=hellosql
$ cd hellosql
Edit the pom.xml file.
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
  http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.bookstore</groupId>
  <artifactId>hellosql</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>hellosql</name>
  <url>http://maven.apache.org</url>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.8.RELEASE</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <properties>
    <java.version>1.8</java.version>
  </properties>

  <build>
    <plugins>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>
Create the Java class that JPA will populate.
package com.bookstore.book;

import org.hibernate.validator.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.util.Date;

@Entity
@Table(name = "books")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, allowGetters = true)
public class Note implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @NotBlank
    private String title;

    @NotBlank
    private String content;

    @Column(nullable = false, updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    @CreatedDate
    private Date createdAt;

    @Column(nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    @LastModifiedDate
    private Date updatedAt;
}
Create the repository
package com.bookstore.book;

import org.springframework.data.repository.CrudRepository;
// will be autoimplemented by the framework
public interface BookRepository extends CrudRepository {}
Create the Controller
package com.bookstore.book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping(path="/book")
public class BookController {
 @Autowired
 private BookRepository bookRepository;

 @GetMapping(path="/add")
 public @ResponseBody String addNewBook (@RequestParam String title
   , @RequestParam int pages
      , @RequestParam String isbn) {

  Book book = new Book();
  book.title = title;
  book.pages = pages;
  book.isbn = isbn;
  bookRepository.save(book);
  return "Saved";
 }

 @GetMapping(path="/all")
 public @ResponseBody Iterable getAllBooks() {
  System.out.println("Controller.getAllBooks()");
  return bookRepository.findAll();
 }
}
Create the app
package com.bookstore.book;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
@EnableJpaAuditing
public class App {
    public static void main( String[] args ) {
        SpringApplication.run(App.class, args);
    }
}
Create the application.properties file in src/main/resources
spring.datasource.url = jdbc:mysql://localhost:3306/bookstore?useSSL=false
spring.datasource.username = databaseuserid
spring.datasource.password = databasepassword
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto = create-drop
Compile and run
$ mvn clean compile
$ mvn spring-boot:run
In the browser create a record by using the following URL:
http://localhost:8080/book/add?title=Star%20Wars&pages=333&isbn=987654321
and the browser responds by printing "Saved". Then view the data by entering the following URL:
http://localhost:8080/book/all
and the browser prints:
[{"id":1,"title":"Star Wars","pages":333,"isbn":"987654321","createdAt":1509937707000,"updatedAt":1509937707000}]

Thursday, November 2, 2017

Babel Commands and npm Project

First Example: Command Line Babel

How to compile (or, more correctly, transpile) ES6 code and run it without having to create project or config files.

Create src/Person.js
export class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.programmingLanguages = [];
  }
  getName() {
    return this.firstName + " " + this.lastName;
  }
}

Create source file src/PersonApp.js
import {Person} from './Person.js';
let lg = new Person('Lady', 'Gaga');
lg.programmingLanguages.push('Javascript','Java','Ruby');

console.log(lg.getName());
console.log(lg.programmingLanguages);
Compile and Run
$ babel --plugins transform-es2015-modules-commonjs src -d bin
src/PersonApp.js -> bin/PersonApp.js
src/Person.js -> bin/Person.js
$ node ./bin/PersonApp.js
Programmer Lady Gaga
Languages Javascript,Java,Ruby
$

Another Example: Command Line Babel

cube.js
export default function cube(x) {
  return x * x * x;
}

cubeApp.js
import cube from './cube.js';
console.log(cube(3));

Compile and Run
$ babel --plugins transform-es2015-modules-commonjs src -d bin
src/cube.js -> bin/cube.js
src/cubeApp.js -> bin/cubeApp.js
$ node ./bin/cubeApp.js
27
$ 

Another Example: Babel Project

$ mkdir -p FirstProject/src
cd FirstProject
$ npm init -y
Wrote to /Users/gMac/dev/src/javascript/tutorials/FirstProject/package.json:

{
  "name": "FirstProject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
$ npm install babel-cli --save-dev
$ npm install babel-preset-es2015 --save-dev
$ npm install babel-preset-stage-0 --save-dev
$ npm install babel-plugin-transform-decorators-legacy --save-dev
$ touch .babelrc
$ touch src/index.js
$ edit ./

.babelrc file in project root
{
  "presets": ["es2015"]
}

src/index.js file
"use strict";
var foo = "bar";
console.log("foo = \"" + foo + "\"");

Compile and run
$ babel src -d bin
src/index.js -> bin/index.js
$ node bin/index.js
foo = "bar"

Final Polish
Edit the package.json file and add the babel command so it looks like this:
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "babel": "babel src -d bin"
  },

And run now the compile using the npm script.
$ npm run babel
$ node bin/index.js
foo = "bar"

Convert to Lambda Style Function

function multiplyBy2(x) {
  return x * 2;
}
console.log(multiplyBy2(10));
> 20

Use the => (ie, rocket or fat arrow) syntax with the following rules:
1. remove the function keyword and use const (or let) instead
2. if only one parameter remove the parentheses
3. remove the curly brackets
4. remove the return keyword

const multiplyByTwo = number => number * 2;
console.log(multiplyByTwo(7));
> 14

Friday, October 27, 2017

Java 8 Streams, Predicates and Lambdas

Eliminate for loops with streams and eliminate if conditionals with predicates and lambdas.

The example on line 63 is the most concise and modern example but, being concise, may not be the easiest to understand initially.

The legacy code example is the method on line 68.

The method on line 78 accepts a predicate but uses a for loop.

The method on line 88 accepts a predicate and uses the stream method instead of a for loop.

Wednesday, October 25, 2017

Java 9 Install with Homebrew

$ brew update
$ brew tap caskroom/cask
$ brew cask install java
$ java -version
java version "9.0.1"

Monday, July 3, 2017

Elixir File IO and List Processing

First steps in Elixir. Simple file IO and parsing in my module Dictionary.ex.
defmodule Dictionary do

  def longest_word do
    IO.puts ("assets/words.txt")
    |> File.read!()
    |> String.split(~r/\n/)
    |> Enum.max_by(&String.length/1)
  end

  def word_list do
    stream = File.stream!("assets/words.txt")
    Enum.each(stream, fn(x) -> IO.puts x end)
  end

  def random_word do
    "assets/words.txt"
    |> File.read!()
    |> String.split(~r/\n/)
    |> Enum.random()
  end
end

Execute With These Terminal and REPL Commands

$ iex -S mix
Erlang/OTP 19 [erts-8.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] 
[kernel-poll:false] [dtrace]

Interactive Elixir (1.4.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1) r Dictionary
warning: redefining module Dictionary (current version loaded from _build/dev/
lib/dictionary/ebin/Elixir.Dictionary.beam)
  lib/dictionary.ex:1

{:reloaded, Dictionary, [Dictionary]}

iex(2)> Dictionary.random_word()
"tourist"

iex(3)> Dictionary.random_word()
"away"

iex(4)> 

Exercise: Get a Tuple From String

This string will be divided by its comma.
iex(15)> stuff = "had we but world enough, and time"

iex(16)> [head | tail] = String.split(stuff, ~r/\,/) 
["had we but world enough", " and time"]

iex(17)> head
"had we but world enough"

iex(18)> tail
[" and time"]

iex(19)>

Exercise: Get a Tuple From String

This string will be divided by its several commas.
iex(26)> gamma = "one,two,three,four,five"
"one,two,three,four,five"

iex(27)> [alpha | omega] = String.split(gamma, ~r/\,/)
["one", "two", "three", "four", "five"]

iex(28)> alpha
"one"

iex(29)> omega
["two", "three", "four", "five"]

iex(30)> gamma = "one, two, three, four, five" 
"one, two, three, four, five"

iex(31)> [first | last] = String.split(gamma, ~r/\,[ ]?/)
["one", "two", "three", "four", "five"]

iex(32)> first
"one"

iex(33)> last
["two", "three", "four", "five"]

iex(34)> 

Pattern Matching Assignment

iex(47)> [a, b, c] = [1, 2, 3]
[1, 2, 3]
iex(48)> a
1
iex(49)> b
2
iex(50)> c
3    
iex(51)> [four, five, six] = [4, 5, 6]      
[4, 5, 6]
iex(52)> four
4
iex(53)> five
5
iex(54)> six
6
iex(55)> 

Sunday, July 2, 2017

Docker

Download and install docker to the Mac's Applications folder and double-click the app to start the docker app.

Start nginex and mongo then kill and restart the nginex container.


$ docker --version
Docker version 17.06.0-ce, build 02c1d87                                                      

$ docker container run --publish 80:80 --detach --name webhost nginx
Unable to find image 'nginx:latest' locally                                                   
latest: Pulling from library/nginx                                                            
e6e142a99202: Pull complete                                                                   
8c317a037432: Pull complete                                                                   
af2ddac66ed0: Pull complete                                                                   
. . .                                                                                         
Digest: sha256:72c7191585e9b79cde433c89955547685db00f3a8595a750339549f6acef7702               
Status: Downloaded newer image for nginx:latest                                               
. . .                                                                                         

$ docker run --name mongo -d mongo
Unable to find image 'mongo:latest' locally                                                   
latest: Pulling from library/mongo                                                            
f5cc0ee7a6f6: Pull complete                                                                   
d99b18c5f0ce: Pull complete                                                                   
. . .                                                                                         
Digest: sha256:f1ae736ea5f115822cf6fcef6458839d87bdaea06f40b97934ad913ed348f67d               
Status: Downloaded newer image for mongo:latest                                               
. . .                                                                                         

$ docker container ls
CONTAINER ID    IMAGE   COMMAND         CREATED       STATUS      PORTS               NAMES   
9f9664b60869    mongo   "docker-en..."  31 sec ago    Up 31 sec   27017/tcp           mongo   
5c1b751f6002    nginx   "nginx -g ..."  41 sec ago    Up 40 sec   0.0.0.0:80->80/tcp  webhost 

$ docker container stop 5c1

$ docker start webhost

Start mysql

$ docker container run -d -p 3306:3306 --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql

Unable to find image 'mysql:latest' locally                                                     
latest: Pulling from library/mysql                                                              
9f0706ba7422: Downloading [===============>                                 ]  16.22MB/52.61MB  
2290e155d2d0: Download complete                                                                 
547981b8269f: Download complete                                                                 
. . .                                                                                           

$ docker container ls -a

CONTAINER ID    IMAGE   COMMAND         CREATED       STATUS      PORTS                  NAMES  
9f9664b60869    mongo   "docker-en..."  31 sec ago    Up 31 sec   27017/tcp              mongo  
5c1b751f6002    nginx   "nginx -g ..."  41 sec ago    Up 40 sec   0.0.0.0:80->80/tcp     webhost
290328842bfd    mysql   "docker-en..."  11 sec ago    Up 10 sec   0.0.0.0:3306->3306/tcp mysql  

Start Apache

$ docker container run -d --name webserver -p 8080:80 httpd

$ docker container ls -a

CONTAINER ID    IMAGE   COMMAND         CREATED       STATUS      PORTS                  NAMES    
6d2bcc3750f6    httpd   "httpd-for..."  10 sec ago    Up 11 sec   0.0.0.0:8080->80/tcp   webserver
290328842bfd    mysql   "docker-en..."  11 sec ago    Up 20 sec   0.0.0.0:3306->3306/tcp mysql    
9f9664b60869    mongo   "docker-en..."  31 sec ago    Up 41 sec   27017/tcp              mongo    
5c1b751f6002    nginx   "nginx -g ..."  41 sec ago    Up 50 sec   0.0.0.0:80->80/tcp     webhost  

Thursday, June 29, 2017

Spring Boot and Angular

Run the following 4 command to implement your development infrastructure:
$ brew install maven

$ brew update && brew install gradle

$ brew tap pivotal/tap

$ brew install springboot
Create your Hello World service with this code:
@RestController
class HelloWorld {
    @RequestMapping("/")
    String home() {
        "Hello World!"
    }
}
Run the app using the following command:
$ spring run app.groovy
Now, open your browser to http://localhost:8080

Monday, June 19, 2017

Using Yarn

$ brew install yarn

$ yarn -v
  yarn install v0.24.6
  info No lockfile found.
  [1/4] 🔍  Resolving packages...
  [2/4] 🚚  Fetching packages...
  [3/4] 🔗  Linking dependencies...
  [4/4] 📃  Building fresh packages...

  success Saved lockfile.
  ✨  Done in 14.27s.

$ yarn run devserver
  yarn run v0.24.6
  Project is running at http://localhost:3000/
  webpack output is served from /

Saturday, June 17, 2017

AWS Command Line Interface

Use pip to install the Amazon Web Services CLI (command line interface) per Amazon's instructions.

$ pip install awscli
$ aws --version
aws-cli/1.11.107 Python/2.7.13 Darwin/16.6.0 botocore/1.5.70


As of the time of this writing, aws-shell which looks as though it may be something similar, is in developer preview so I will ignore it for the remainder of this post.

Once you have the CLI installed, you will need to navigate your browser to http://console.aws.amazon.com and create an account if you do not yet have one and then access 'My Security Credentials' under your account settings which are in the upper right of the screen.

Click 'Create Secure Access Key' on the security credentials screen and download the file that Amazon generates. Once downloaded, open the rootkey.csv file with TextEdit. Run the aws configure command and enter the ID and key values in the CSV file where ID and Key are prompted for. Note that us-east-2 is the region for my location of Dallas.

$ aws configure
AWS Access Key ID [None]: __________
AWS Secret Access Key [None]: __________
Default region name [None]: us-east-2
Default output format [None]: json 


Friday, June 16, 2017

Generate Map from Lat/Lng

Use node.js to run the 'hello world' app of the Leaflet web mapping Javascript library.

Create a folder, install the leaflet GIS library code using npm, add the two source files from below and then start the server and open the URL in your browser.


<html>
<!-- index.html -->
<head>
    <link rel='stylesheet' href='src/leaflet/leaflet.css' />
    <script src='src/leaflet/leaflet.js' type='text/javascript'></script>
    <style type="text/css">
        html,
        body {
            height: 100%;
            overflow: hidden;
        }
        
        #map {
            height: 100%;
        }
    </style>
</head>

<body>
    <div id='map'></div>
    <script>
        var map = new L.Map('map', {
            center: [37.770, -122.41],
            zoom: 10
        });

        L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
            attribution: '© OpenStreetMap contributors'
        }).addTo(map);

    </script>
</body>

</html>
//server.js
var connect = require('connect');
var serveStatic = require('serve-static');
connect().use(serveStatic(__dirname)).listen(8080, function() {
    console.log('Server running on 8080...');
});

Wednesday, June 14, 2017

Angular CLI

A new course on pluralsight.com teaches the fundamentals on the Angular CLI (command line interface).
$ ng i @angular/cli -g
$ ng -v
    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / △ \ | '_ \ / _` | | | | |/ _` | '__|  | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
               |___/
@angular/cli: 1.1.1
node: 7.4.0
os: darwin x64
@angular/animations: 4.2.2
@angular/common: 4.2.2
@angular/compiler: 4.2.2
@angular/core: 4.2.2
@angular/forms: 4.2.2
@angular/http: 4.2.2
@angular/platform-browser: 4.2.2
@angular/platform-browser-dynamic: 4.2.2
@angular/router: 4.2.2
@angular/cli: 1.1.1
@angular/compiler-cli: 4.2.2
@angular/language-service: 4.2.2

$ ng new my-dream-app
$ npm install
$ cd my-dream-app
$ ng serve
$ open http://localhost:4200

JUnit 4

Download junit and hamcrest jar files.

Create the class under test and the test.

public class Calculator {
  public int evaluate(String expression) {
    int sum = 0;
    for (String summand: expression.split("\\+"))
      sum += Integer.valueOf(summand);
    return sum;
  }
}


import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class CalculatorTest {
  @Test
  public void evaluatesExpression() {
    Calculator calculator = new Calculator();
    int sum = calculator.evaluate("1+2+3");
    assertEquals(6, sum);
  }
}

Compile both classes then run.
javac Calculator.java

javac -cp .:junit-4.12.jar:hamcrest-core-1.3.jar CalculatorTest.java

java -cp .:junit-4.12.jar:hamcrest-core-1.3.jar org.junit.runner.JUnitCore CalculatorTest
JUnit version 4.12
.
Time: 0.025

OK (1 test)

Alternate version with Maven in github

Inventory by Functional Javascript

The purpose of this exercise is to learn how to use forEach, map and reduce together.

First, create the inventory data structure then the two functions that wrap map and reduce.

Then refine the use of the data structure and the functions until we get the result we desire, the value of the all the items by brand.
> var inventory = [
    { brand: 'Nike',    
      items: [
        {name: 'Air Jordan', price: 100}, 
        {name: 'Air Max', price: 120}
      ]
    },
    { brand: 'Adidas', 
      items: [
        {name: 'Super Star', price: 99}, 
        {name: 'Racer', price: 151}
      ]
    }
  ];

> var computeSum = function(valuesMap) {
    return valuesMap.reduce(function(tot, val) { return tot + val; }, 0);
  }

> var computeTotalCost = function(items) {
    var prices = items.map(function(item) { return item.price; });
    return computeSum(prices);
  }

> computeTotalCost(inventory[0].items)
  220

> computeTotalCost(inventory[1].items)
  250

> inventory.forEach(function(elem) {console.log(elem.brand)})
  Nike
  Adidas

> inventory.forEach(
    function(elem) {
      elem.items.forEach(
       function(item) {
         console.log(item.price )
       }
     )
    }
  )
  100
  120
  99
  151

> inventory.forEach(
    function(elem) {
      console.log(elem.brand + ": " + computeTotalCost(elem.items))
    }
  )
  Nike: 220
  Addidas: 250


The last step produces the info we need, the brand name and the value of the inventory. What we do now is make the values portable by creating a new object inventoryTotals and, using the functions that wrap map and reduce, place the brand name and total for that brand in it.

> inventoryTotals = {};

> inventory.forEach(
    function(elem) {
      inventoryTotals[elem.brand] = computeTotalCost(elem.items);
    }
  )

> inventoryTotals
  Object {Nike: 220, Addidas: 250}

Saturday, June 3, 2017

F# Functions

In Visual Studio Code enter the following code then, to run it, highlight it and press Option Enter:
let helloWorld = 
    "Hello from FSI"

printfn "%s" helloWorld
and get this result:
Hello from FSI
In Visual Studio Code enter the following code then, to run it, highlight it and press Option Enter:
let prefix preStr postStr = 
  preStr + ", " + postStr

prefix "Hello" "Greg"
and get this result:
val it : string = "Hello, Greg"
In Visual Studio Code enter the following code then, to run it, highlight it and press Option Enter:
let names = ["Joe"; "Sue"; "Mary"; "Bill"]

names
|> Seq.map (prefix "Hello")
and get this result:
val it : seq =
  seq ["Hello, Joe"; "Hello, Sue"; "Hello, Mary"; "Hello, Bill"]

Breeze, a Numerical Processing Library for Scala

Per the github repo, Breeze is a generic, clean and powerful Scala numerical processing library patterned after NumPy, Matlab and R.


On a Mac, install SBT using homebrew.
$ brew install sbt

$ sbt
> set scalaVersion := "2.11.7"

> set libraryDependencies += "org.scalanlp" %% "breeze" % "0.12"

> set libraryDependencies += "org.scalanlp" %% "breeze-viz" % "0.12"

> console

scala> import breeze.linalg._

scala> import breeze.numerics._

scala> val vec = DenseVector(1.0, 2.0, 3.0)
vec: breeze.linalg.DenseVector[Double] = DenseVector(1.0, 2.0, 3.0)

scala> vec:+ DenseVector(4.0, 5.0, 6.0)
res0: breeze.linalg.DenseVector[Double] = DenseVector(5.0, 7.0, 9.0)

scala> DenseVector.zeros[Int](3)
res1: breeze.linalg.DenseVector[Int] = DenseVector(0, 0, 0)

scala> DenseVector.tabulate(4) {i=> 5.0 * i}
res2: breeze.linalg.DenseVector[Double] = DenseVector(0.0, 5.0, 10.0, 15.0)

scala> val nums = Seq(2, 3, 4)
nums: Seq[Int] = List(2, 3, 4)

scala> DenseVector(nums:_*)
res5: breeze.linalg.DenseVector[Int] = DenseVector(2, 3, 4)

scala> :q

> exit

$ 

Tuesday, April 25, 2017

A Classic is Now Free

The Wizard book written by MIT professors Abelson and Sussman teaches the principles of computer programming and MIT has made it freely available for download.

https://mitpress.mit.edu/sites/default/files/6515.pdf

Sunday, April 23, 2017

JVM Profiling

To produce a histogram of all the Java types running in a process (a JVM) first use jps to get the process id of the JVM then use jmap to produce the histogram.

$ jps
32111 Main
$ jmap 32111 -histo 32111 | less

Saturday, March 18, 2017

First Python Machine Learning

This 7 minute youtube video shows how to write your first machine learning program.
from sklearn import tree

features = [[140, 1], [130, 1], [150, 0], [170, 0]]
labels = [0, 0, 1, 1]

clf = tree.DecisionTreeClassifier()
clf = clf.fit(features, labels)

print( clf.predict([[160, 0]]) )

Run with this command:
python hello_machine.py
[1]

Wednesday, March 15, 2017

Objective-C Tutorial Exercise 1

Note use of prototypes declared on lines 3, 4 and 5 while the procedures are defined on lines 22, 26 and 32.
Also note use of static keyword on line 33.

Python Exercise 1

Create a Countdown Clock

When clock completes its countdown, start the video!
import time
import sys
import webbrowser

def countdown(secs):
    while secs:
        mx, sx = divmod(secs, 60)
        timeformat = '{:02d}:{:02d}\r'.format(mx, sx)
        print timeformat,
        sys.stdout.flush()
        time.sleep(1)
        secs -= 1

countdown(2 * 3 * 2)
webbrowser.open("http://www.youtube.com/watch?v=dQw4w9WgXcQ")

Friday, February 24, 2017

Thursday, December 8, 2016

MacBook Camera (Photo Booth) Not Working

Why does the MacBook's built-in webcam not work? Not sure but the fix is

sudo killall VDCAssistant

Wednesday, November 23, 2016

Ruby Blocks

Yield Blocks
def test_to_call_block
   puts "method"
   yield          # execute the block with yield
   puts "method"
   yield          # execute the block with yield
end
# call the method, passing it a block
test_to_call_block {puts "block"}
Running the code above results in:
C:\>ruby test_to_call_block.rb
method
block
method
block
Another Example Using Alternate Syntax
# define the method
def my_method(&block) 
  puts "in my_method"
  yield
  puts "back in my_method"
end

# call the method, passing it a block wrapped with do/end
my_method do 
  puts "Hello"
end
Running the code above results in:
C:\>ruby blocks.rb
in my_method
Hello
back in my_method
Block Parameters
def yield_with_parm(&block) 
  yield 1
  yield 2
  yield 3
end

# call the method, passing it a block
yield_with_parm do | param |
  puts param
end
Running the code above results in:
C:\>ruby yield_with_parm.rb
1
2
3
Another Example of Block Parameters
def yield_with_parm
   yield 5
   puts "You are in the method"
   yield 100
end
yield_with_parm {|i| puts "You are in the block #{i}"}
Running the code above results in:
C:\>ruby yield_with_parm.rb
You are in the block 5
You are in the method
You are in the block 100
DRY Reuse: each with yield
prices = [3.99, 4.79, 0.99]

def each
  index = 0
  while index < self.length
    yield self[index]
    index += 1
  end
end

def total(prices)
  amount = 0
  prices.each do |price|
    amount += price
  end
  amount
end

def show_discounts(prices)
  prices.each do |price|
    discount = price * 0.05
    puts format("Discount = $%.2f", discount)
  end
end

puts format("Total = $%.2f", total(prices))
show_discounts(prices)
Running the code above results in:
C:\>ruby blocks.rb
Total = $9.77
Discount = $0.20
Discount = $0.24
Discount = $0.05
Yielding with Multiple Parms
#define the method
def yielding_method 
  yield "a", "b"
end
# call yielding_method passing it a block
yielding_method {|*vals| 
  vals.each do |i|
    puts("printing #{i}")
  end
}
Running the code results in:
C:\>ruby multi_parm_yield.rb
printing a
printing b

Wednesday, November 16, 2016

From NeXTSTEP to Cocoa Interview

Interview of Erik Buck on the Development of Cocoa and Objective-C From NeXTSTEP to Cocoa

Object-oriented programming languages fall into two major categories: those inspired by Simula and those inspired by Smalltalk.

C++ is a language that grafts Simula-style object orientation onto the C programming language while simultaneously trying to improve C.

Objective-C is a language that grafts Smalltalk style message sending onto C while preserving the base C language unchanged.

... Microsoft's C# .NET Framework is becoming very Cocoa like. Microsoft has finally embraced the Model View Controller design pattern that is ubiquitous in Cocoa. The C# language is evolving to be closer in concept to Objective-C.

(In Objective-C) Network distributed messages use identical syntax to local messages.

The Gang of Four frequently cite examples of their patterns not only in Smalltalk but in NeXTstep.... the Objective-C language makes many of the original Gang of Four design patterns trivial or unnecessary.

Tuesday, November 15, 2016

Javascript Terminology

Expression - any valid set of literals, variables and operators. An expression produces a value.

Whenever Javascript expects a statement, an expression may be used but not vice versa. For instance, a statement may not be an argument passed to a function.

A call of a function is an expression.

The grouping operator ( ) controls the precedence of evaluation in expressions.

Statement - produces an action, such as an assignment statement or changes to the flow of the execution of code such as an IF statement

Complex Statement - A complex statement is a sequence of statements inside {}

Thursday, November 3, 2016

Today's Haskell

? let xRepeater x2r = [ if (odd x) then x else x * 2 | x <- x2r ]
? xRepeater [3..6]
> [3,8,5,12]

? let xFilter x2f = [ x | x <- x2f, x /= 5 ]
? xFilter [3..6]
> [3,4,6]

? [x | x <- [50..100], x `mod` 7 == 3]
> [52,59,66,73,80,87,94]

? [x | x <- ["one", "two", "three", "four", "five", "six"], length x > 3]
> ["three","four","five"]

Monday, October 24, 2016

Non-blocking DB Driver

IBM's upcoming non-blocking DB driver for their big POWER processor machines: http://ibm.co/2bh9XoB

Tuesday, October 18, 2016

Friday, September 23, 2016

Functional Javascript - From Table to Objects

I modified the cvs example in Michael Fogus' book "Functional Javascript" to create an array of objects from a table. First example has a little hard-coding which is bad but that is eliminated in the following example. The third example uses _.object which is nice but a little magical for a beginner like me.



Without underscore:

Here we see that default values are declared for the arguments and a default return value! When no arguments are passed, the function returns a empty object.
function calcSalesTotal(total = 0, taxRate = 0.15 } = {}) {
    return total + (total * taxRate);
}

Tuesday, August 9, 2016

Functional Java with Stream, Filter, Map and Collect

I played around with exercises from chapter 2 of "Java 8 in Action". I modified the example that uses stream(), filter(), map() and collect() and I added a predicate that uses enums.

Thursday, July 28, 2016

npm install -g create-react-app

Something interesting to look at, create apps with NO configuration.

Wednesday, July 6, 2016

Some SCALA

object MyModule {

  def abs (n: Int): Int =
    if (n < 0) -n
    else n

  private def formatAbs(x: Int) = {
    val msg = "The absolute value of %d is %d"
    msg.format(x, abs(x))
  } 

  def main(args: Array[String]): Unit = 
    println(formatAbs(-42))

}
scala> :load MyModule.scala
scala> MyModule.main(Array(""))
The absolute value of -42 is 42


scala> def position(l: List[String], s: String):Int = {l.indexOf(s)}
position: (l: List[String], s: String)Int

scala> position(numList,"one")
res3: Int = 0

scala> position(numList,"two")
res4: Int = 1

scala> position(numList,"three")
res5: Int = 2

scala> numList.foreach(println)
one
two
three

scala>

Friday, July 1, 2016

Testing Javascript with Mocha

Testing palindrome code with Mocha.



As shown below, on the AS400, in the qp2term terminal, run the install and the test in the same way.


Sunday, June 19, 2016

8 Inch Floppies

You may have read recently that the United States nuclear forces still rely on eight inch floppy discs for data storage and that for many years all pass codes on the nuclear missle firing locks were zero, zero, zero, zero. Well, the United States nuclear forces aren't the only ones living in the past. Let's familiarize ourselves with legacy service integration practices.

In Sam Newman's book "Building Microservices", he states that the shared database is the most common means of service integration. This form of integration was explained to me by the Java architects I worked with a dozen years ago at a legacy AS400 mainframe shop when I asked, "Why can't they modernize their database?". In this form of service integration, a company simply places all its data in one database on one DB server and the applications from every line of business were free to read and modify the data of all other lines of business. This might include HR, purchasing, sales, retail and warehouse for a retailer.

This situation makes immediately clear the problem that SOA addresses, to develop provider and consumer services that are loosely coupled. How is loose coupling achieved? By providing services that have descriptive, rather than instructive, interfaces.

Once the loose coupling of service oriented architecture is achieved, change is simpler, cheaper and faster to achieve. When applications are no longer coupled to each other's tables, the effort, time and expense involved in modifying them is greatly reduced.

Tuesday, May 31, 2016

How to Use pseudouser

/apps/geogoogle is owned by the s_geogle pseudouser. If you want to copy data into a directory owned by it, a typical method would be:

Place db.properties file in /apps/tmp/
sudo su – s_geogle
cd /apps/geogoogle
cp /apps/tmp/db.properties .
(or)
cp /apps/tmp/db.properties /apps/geogoogle/db.properties


Sunday, May 29, 2016

bash Process Substitution

Bash will automatically parallelize your tasks.

Replace
$ curl http://somesite/file1 > file1
$ curl http://somesite/file2 > file2
$ diff file1 file2

with
$ diff <(curl http://somesite/file1) <(curl http://somesite/file2)

Friday, May 27, 2016

Node Producer and Consumer Apps

In one command terminal, run server.js and in a second command terminal run client_requestify.js. The console running server.js will show the log "who=Greg" and the terminal running client_requestify.js will display "hello Greg!".

Saturday, May 14, 2016

Getting Started with ExtJS and Sencha

After installing Sencha and ExtJS, I have two folders
  • Sencha
  • ext-6.0.2
I create the folder sencha_apps.
$ cd sencha_apps

$ export PATH=$PATH:~/dev/lib/Sencha/Cmd

$ export PATH=$PATH:~/dev/lib/Sencha/Cmd/6.1.2.15

$ sencha -sdk ~/dev/lib/ext-6.0.2/cmd generate app App01 app01
Sencha Cmd v6.1.2.15
[INF] Processing Build Descriptor : classic
[INF] Loading app json manifest...
...
...

$ cd app01

$ ls -al
total 488
drwxr-xr-x  22 gMac  staff     748 May 14 20:35 .
drwxr-xr-x   3 gMac  staff     102 May 14 20:34 ..
drwxr-xr-x   6 gMac  staff     204 May 14 20:35 .sencha
-rw-r--r--   1 gMac  staff    4615 May 14 20:35 Readme.md
drwxr-xr-x   7 gMac  staff     238 May 14 20:35 app
-rw-r--r--   1 gMac  staff     990 May 14 20:35 app.js
-rw-r--r--   1 gMac  staff   18280 May 14 20:35 app.json
-rw-r--r--   1 gMac  staff     303 May 14 20:35 bootstrap.css
-rw-r--r--   1 gMac  staff  101584 May 14 20:35 bootstrap.js
drwxr-xr-x   4 gMac  staff     136 May 14 20:35 build
-rw-r--r--   1 gMac  staff    1465 May 14 20:35 build.xml
drwxr-xr-x   4 gMac  staff     136 May 14 20:35 classic
-rw-r--r--   1 gMac  staff   58181 May 14 20:35 classic.json
drwxr-xr-x  22 gMac  staff     748 May 14 20:35 ext
-rw-r--r--   1 gMac  staff    1974 May 14 20:35 index.html
drwxr-xr-x   4 gMac  staff     136 May 14 20:35 modern
-rw-r--r--   1 gMac  staff   36134 May 14 20:35 modern.json
drwxr-xr-x   2 gMac  staff      68 May 14 20:35 overrides
drwxr-xr-x   2 gMac  staff      68 May 14 20:34 packages
drwxr-xr-x   3 gMac  staff     102 May 14 20:35 resources
drwxr-xr-x   8 gMac  staff     272 May 14 20:35 sass
-rw-r--r--   1 gMac  staff    1486 May 14 20:35 workspace.json

$ sencha app build
Sencha Cmd v6.1.2.15
[INF] Processing Build Descriptor : classic
[INF] Loading app json manifest...
...
...

$ sencha web start
Sencha Cmd v6.1.2.15
[INF] Starting server on port : 1841
[INF] Mapping http://localhost:1841/ to ....

Opening the browser to http://localhost:1841 I see a pretty nice web page.

Friday, May 13, 2016

Getting Started with Vagrant and Docker

Vagrant installs on Windows from a MSI download.
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\gah285>vagrant --version
Vagrant 1.8.1

C:\Users\gah285>vagrant init precise64 http://files.vagrantup.com/precise64.box
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

C:\Users\gah285>vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
...
...
...

C:\Users\gah285>vagrant ssh
`ssh` executable not found in any directories in the %PATH% variable. Is an
SSH client installed? Try installing Cygwin, MinGW or Git, all of which
contain an SSH client. Or use your favorite SSH client with the following
authentication information shown below:

Host: 127.0.0.1
Port: 2222
Username: vagrant
Private key: C:/Users/gah285/.vagrant/machines/default/virtualbox/private_key

I take the advice given in the error message and I added the GIT path to the system path in order to utilize that copy of ssh.
C:\Users\gah285>set PATH=%PATH%;c:\progra~1\git\usr\bin

C:\Users\gah285>vagrant ssh
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)

 * Documentation:  https://help.ubuntu.com/
New release '14.04.4 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

Welcome to your Vagrant-built virtual machine.
Last login: Fri Sep 14 06:23:18 2012 from 10.0.2.2
vagrant@precise64:~$

Tuesday, May 10, 2016

Sunday, May 8, 2016

Trump 2.0

Trump often presents a new version of his beliefs and policy positions.

Trump's flipflops:
  1. 2nd Amendment
  2. Abortion
  3. H1-B Visas
  4. tax rate for the rich
  5. minimum wage
  6. his marriage vows
  7. Not relying on super-pacs and self financing his campaign
  8. In 2013 Trump stated: "We will have to leave borders behind and go for global unity ...."
Trump's lies:
  1. his support of the 2003 Iraq war
  2. knowing Putin
  3. his infidelities
  4. masquerading as his own publicist


Tuesday, May 3, 2016

Practical Probabilistic Programming with Scala and Figaro

The book "Practical Probabilistic Programming" details the use of the Scala programming language, the sbt tool and the Figaro machine learning library to predict and infer reasoned conclusions.



Thursday, April 28, 2016

Java Pub/Sub

The beta version of reactive programming is the traditional pub/sub app. It seems plausible that several instances of the same class may want to be in a pub/sub relationship so I wanted to code a class that would provide that and, of course, make the simplest working example in the fewest lines of code.

Sunday, April 24, 2016

RxJava

The book "Learning Reactive Programming with Java 8" presents a console program that accepts values a and b from the console input stream in the form "a=N" and "b=N" where N is any number and by subscribing on the Observables, recalculates the sum as values for a and b are entered at the console. See the "run command and results" section below.

Thursday, March 31, 2016

Linux No Hangup Command

nohup ./runcmd.sh > /dev/null 2>&1 & 

Then verify the java app is running with the pgrep command -
$ pgrep -l java
21428 java
60020 java

Saturday, March 26, 2016

Getting Started with Apache Spark

Gregorys-iMac-2:spark-1.6.1 gMac$ ./bin/spark-shell
ls: /Users/gMac/dev/bin/spark-1.6.1/assembly/target/scala-2.10: No such file or directory
Failed to find Spark assembly in /Users/gMac/dev/bin/spark-1.6.1/assembly/target/scala-2.10.
You need to build Spark before running this program.
Gregorys-iMac-2:spark-1.6.1 gMac$ build/mvn -Pyarn -Phadoop-2.4 -Dhadoop.version=2.4.0 -DskipTests clean package
exec: curl --progress-bar -L http://downloads.typesafe.com/zinc/0.3.5.3/zinc-0.3.5.3.tgz
######################################################################## 100.0%
. . .
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 20:24 min
[INFO] Finished at: 2016-03-26T14:47:06-05:00
[INFO] Final Memory: 89M/1351M
[INFO] ------------------------------------------------------------------------
Gregorys-iMac-2:spark-1.6.1 gMac$ ./bin/spark-shell
log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Using Spark's repl log4j profile: org/apache/spark/log4j-defaults-repl.properties
To adjust logging level use sc.setLogLevel("INFO")
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 1.6.1
      /_/

Using Scala version 2.10.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_66)
Type in expressions to have them evaluated.
Type :help for more information.
Spark context available as sc.
SQL context available as sqlContext.

scala> val textFile = sc.textFile("README.md")
textFile: org.apache.spark.rdd.RDD[String] = README.md MapPartitionsRDD[3] at textFile at :27

scala> textFile.count()
res1: Long = 95

scala> textFile.first()
res2: String = # Apache Spark

scala> 

Monday, March 21, 2016

Haskell Functions and Lists

Haskell is a quick and easy install on Windows and the Mac. The book, "Learn You a Haskell For Great Good!", is a quick and easy way to get started with the language.

Start the interpreter and set the prompt:
C:\> ghci
Prelude> :set prompt "ghci> "
ghci>  
Prelude> let first x = head x
Prelude> first ['a', 'b', 'c', 'd']
'a'
Prelude> let myList = ['a', 'b', 'c', 'd']
Prelude> first myList
'a'
Prelude> tail myList
"bcd"
Prelude> 
Prelude> 'a': ' ' : "small cat"
"a small cat"
Prelude> "a " ++ "small cat"
"a small cat"
Prelude> tail "a " ++ "small cat"
" small cat"
Prelude> init "a " ++ "small cat"
"asmall cat"
Prelude> init ("a " ++ "small cat")
"a small ca"
Prelude>
Prelude> let doubleMe x = x + x
Prelude> doubleMe 4
8
Prelude> let doubleUs x y = doubleMe x + doubleMe y
Prelude> doubleUs 7 3
20
Prelude>
In ghci, the Haskell REPL, 'let' is necessary to define a name but 'let' is not necessary in a script.
Prelude> let boomBang =[if x `mod` 2 == 0 then "BANG!" else "BOOM!" | x <- [1 .. 10]]
Prelude> boomBang
["BOOM!","BANG!","BOOM!","BANG!","BOOM!","BANG!","BOOM!","BANG!","BOOM!","BANG!"]
Prelude>
Prelude> let myCharData = "Now is The Time For All Good Men to Come to The AID of THEIR cOunTry"
Prelude> let removeUpper st = [c | c <- st, c `elem` ['a' .. 'z']]
Prelude> removeUpper myCharData
"owisheimeorlloodentoometoheofcunry"
Prelude>
Prelude> let myCharData = "Now is The Time For All Good Men to Come to The AID of THEIR cOunTry"
Prelude> let removeUpper st = [c | c <- st, c `elem` ' ': ['a' .. 'z']]
Prelude> removeUpper myCharData
"ow is he ime or ll ood en to ome to he  of  cunry"
Prelude>
Lists:
Prelude> take 10 [1..]
[1,2,3,4,5,6,7,8,9,10]
Prelude> take 10 [33..]
[33,34,35,36,37,38,39,40,41,42]
Prelude> take 10 ['a'..]
"abcdefghij"
Prelude> [3.0, 2.75..0]
[3.0,2.75,2.5,2.25,2.0,1.75,1.5,1.25,1.0,0.75,0.5,0.25,0.0]
Prelude> take 10 [1.0, 1.25..]
[1.0,1.25,1.5,1.75,2.0,2.25,2.5,2.75,3.0,3.25]
Prelude>
Tell ghci to print type information:
Prelude> 'c'
'c'
Prelude> :set +t
Prelude> 'c'
'c'
it :: Char
Prelude> :unset +t
Prelude>
Ratios
Prelude> 11 % 29

:12:4: Not in scope: `%'

Prelude> :m +Data.Ratio
Prelude Data.Ratio> 11 % 29
11 % 29
Prelude Data.Ratio> :set +t
Prelude Data.Ratio> 11 % 29
11 % 29
it :: Integral a => Ratio a
Prelude Data.Ratio>