Sunday, 7 June 2015

California, Arizona, Utah, Nevada (late Apr to May 2015 Actual Trip)

LA Blog (Photos PENDING Upload)
  • 20 Apr Mon
    • Arrived LA. Airport transfer to Travelodge in Anaheim was $60. Walked down the road. Luke got a haircut. Purchased burritos.
  • 21 Apr Tues
    • Walked to Disneyland and spent the day there (walking distance from hotel). We bought the one park per day deal)
    • We enjoyed a yummy crepe at a chain restaurant called IHOP (similar to Pancakes on the Rocks in Sydney) for dinner. 
    • Baseball game to watch the LA Angels vs Oakland Athletics (A's) was walking distance away
  • 22 Apr Wed
    • Walked to Disney Adventure Park (also walking distance from hotel)
    • Collected hire car from down the road at Hertz as they offered unlimited miles. Booked to return it to same location in Anaheim (South East LA) on the 28th Apr (it only cost ~$160 to hire a car for 6 days when returning it to the same location, whereas if we were to return it to a different hire car location it cost significantly more at ~$900)
    • Drove to the Staples Stadium to watch the LA Clippers vs San Antonio Spurs at 7:30pm (McDonald's extra fries and coke at stadium was an extra $6). We got home at midnight as Anaheim is about 1 hr drive from the city. Highways have about 6-7 lanes in many parts, and they are made from slabs of concrete, so for most of the trip every 1-2 seconds you feel a little hump, which feels cool as the suspension is quite soft, and we're in a standard sized sedan (Nissan Altima). 
    • Drove on the right hand side, and the fuel is measured in gallons instead of litres. Food is very tasty and they give generous servings that are mostly cheaper than back home. Lunch was a tasty chicken pasta, and we found a chocolate fudge shop in Disney Adventure Park and pigged out on a chocolate fudge icecream. 
    • Booked a Train (with bus transfer included) for us to catch at about 10am on 29th Apr (costing ~$120 for both of us), which would take us to San Francisco and have us arrive there in the evening at about 11pm so we could check into a cheap backpackers accommodation at Fisherman's Wharf costing ~$90 in shared dorms before heading off on our tour around San Francisco and the drive out to Yosemite National Park
  • 23 Apr Thu
    • Checked out of hotel late at about 11am.
    • Drove from Anaheim to Newport Beach and saw boats moored on the inlet, continued down to Laguna Beach and saw whales off the coast. 
    • Ate BJ's take-away Deep Pizza for lunch (delicious) 
    • Drove up to Long Beach via Seal Beach. Got lost around Vincent Thomas Bridge (incredibly high and surrounded by large port with many cranes). 
    • Drove to Redondo Beach, Manhattan Beach with free beach volleyball setup, noticed larger seagulls and drill rigs off the coast. 
    • Drove past Marina Del Ray and drove past Venice Beach but it was dark at 7:30pm with only a couple of streets with coloured lights and activity, but it was difficult to park the car. Nearby Main St had glittery lights. 
    • Continued along the Pacific Coast Drive to Santa Monica and after finding free Wifi at a service station we found accommodation at Palm Motel costing $85 + $13 tax and checked in at about 9:30pm.
  • 24 Apr Fri
    • Drove to Los Vegas
    • Stopped at Route 66 Museum. Drove via old Route 66 from there to Ghost Town where there were small dust storms but it was closed
    • Arrived in Los Vegas at Hostel Cat and joined their tour of Old Los Vegas at 10:30pm. Did not realise each drink was a double shot after the first
  • 25 Apr Sat
    • Hung over slept in until 4pm
    • Walked around Los Vegas strip from 4pm until 5:30am the next morning
    • Met an Austrian backpacker (Georg) and offered for him to join us on our drive out to the Grand Canyon area
  • 26 Apr Sun
    • Drove from LA to Flagstaff
    • Visited the Hoover Dam and did the tour
    • Visited the West Rim of Grand Canyon and paid entry fee of $40 each. Parked car and boarded bus that took us to the two lookouts. Watched sunset at second lookout.
    • Arrived at Flagstaff at approx midnight. Stayed at Americas Best Value Inn & Suite. Saw a small bus stuck hanging slightly off the road and checked it was not an accident when arriving in Flagstaff.
  • 27 Apr Mon
    • Drove South to Sedona via main highway and returned via tourist route of Red Rock National Park. Stopped at lookouts including a bridge lookout. Did the Grasshopper hike but Luke got directions wrong and we crossed the river early and struggled through thick vegetation until reaching the correct crossing. Returned back to car. Saw large yellow butterflies.
    • Drove through Kaibab National Park before entering South Rim of Grand Canyon National Park. Payed only $25 for private vehicle (with 3x passengers). Drove to each of the lookouts. We walked partly down a hike at sunset.
  • 28 Apr Tues
    • Drove initially from Knights Inn in Page to the North. Only 5 mins out of town was Grand Canyon Dam and a turn-off to the right with a great 360 degree view of Lake Powell with canyon scenery, then soon after we turned off to Visitor Center at Evan ___, where we were informed that Vermillion Cliffs was along 89A to the South via the Colorado river.
    • Drove back to Page. Continued to Navajo bridge that crossed Colorado River.
    • Drove along the edge below Vermillion Cliffs and Marble Canyon
    • Stopped for photos with large boulders in Marble Canyon
    • Diverted off highway to the left to Coral Pink Sand Dunes and returned to highway again
    • Entered Dixie National Forest
    • Arrived at Bryce Canyon, viewed all photo points. Saw chipmonk and ravens flying together. Did the hike from Sunset Point to Sunrise Point just before sunset. Continued driving to Fairyland Point to find motorcycle slid off road just before turn-off but just made it before dark
    • Drove back to main highway by 8pm.
  • 29 Apr Wed
    • Drove back to Anaheim, got lost initially at wrong Motel 6, and stayed at Motel 6 (in Stanton). Stopped on the way at St George for dinner at IHOP (Luke had omlette and pancakes, Claudia had blue cheese steak with salad/veges)
    • Farewelled Georg
    • Arrived at Motel 6 at 5:30am, fortunately before going to bed we checked Amtrack website for status of Train 14 to San Francisco and found it did not exist. After calling Amtrack we found we had to get to Union Station in LA (in the city instead of out of town at Anaheim Station). We returned car early at 7:50am after clocking up ~2100 miles and ran to Anaheim Station (Luke thought it was 10 min walk according to Google Maps, but later discovered it was actually 10,000 feet (2.5km) upon later reflection) and boarded (clothes sweating profusely and red faced and out of breathe) train that left at 9:15am and arrived Union Station at 10:00am. Ran down ramp to tunnel, asked for Amtrack ticket finalisation counter, we were informed Amtrack was at other end of tunnel so ran there past golf cart courtesy buggies, whistled Claudia's attention when found it and were informed that electronic receipt ticket was sufficient (on iPhone), ran back to other end and along platform at 10:10am, guard yelled to stop running and that they would wait for us. 
    • Changed clothes on train. Luke had vege burger and half bottle red wine for lunch, and Black Angus/mash/beans with half bottle white wine for dinner. Claudia had chicken schnitzel/mash for lunch and salmon/mash/veg for dinner
  • 29 Apr Wed
    • Arrived at accommodation at 10:30pm. Met a man who was on business for a water business in San Francisco who was staying at same accommodation. Booked accommodation at Yosemite and car hire (Hertz). 
    • Slept from 2:30am
  • 30 Apr Thur
    • Woke up at 7am. Went to Pier 33 via Pier 39 by foot for the Alcatraz Island Tour ($30 each) from 10am and returned to shore at 2:15pm.
    • Picked up hire car from Hertz (Chevy Cruz with GPS). Collected luggage from accommodation
    • Drove toward East bridge but too much traffic. Took exit and headed North to Golden Gate bridge. Stopped for the view point at North end of Golden Gate
    • Drove further North and followed signs to Muir Woods. Met someone who worked for National Park in Alaska for 15 years who was taking photos and selling them during Denali Adventures. Chatted with him until 8:30pm. 
    • Drove toward accommodation. Ate full baby back ribs at Applebees in Livermore.
    • Arrived accommodation 2:30am.
  • 1 May Fri
    • Woke up at 9am
    • Drove to Old Railway but they only had fixed ride times and we missed the morning rides. Continued to Muir Woods and hiked up to the top Point and down again by sunset. 
    • Drove to Glacier Point and saw a wolf or coyote on the way
    • Ate noodles for dinner
  • 2 May Sat
    • Drove to Yosemite National Park Village. 
    • Walked part of the Four Mile Walk (were told incorrectly that there were no shuttle buses but there were some!)
    • Walked around beach area and had lunch with ravens and ducks
    • Horse ride to Mirror Lake for 2 hrs 
    • Walked to Vernon Falls and to the base of Nevada Fall and got back to road by dark
    • Saw people climbing up the Half Dome at night since it was a full moon
    • Drove back to accommodation via the West route by mistake and had Taco Bell for dinner since everything else closed at 11pm
  • 3 May Sun
    • Drove back to Yosemite Valley. Walked to Yosemite Lower Falls. Drove toward Hecky Hecky. Walked the Carlon Falls trail to its waterfall and back again. Drove further to the Hecky Hecky dam. 
    • Stayed at hostel for cheap just outside Yosemite on Western side and had dinner at a roadhouse down the road
  • 4 May Mon
    • Drove the Tioga Road and stopped off along the way
    • Stayed at Bridgeport Inn. They had advertised online for $69 with free breakfast. We arrived by car and they agreed to $69 to Claudia, but they only gave her a voucher for $3.50 from a meal. I came in and showed them the online deal that advertised free breakfast and they said they had no problem providing free breakfast and the manager would be available in the morning. When entering the motel entrance with our luggage a lady with blonde hair who was from the bar was intending to exit at the same time. I opened the door and said "after you", and she proceeded through. I entered with my backpack and Claudia followed with hers. She made no attempt to offer to help. She must have heard me complaining about their false advertising and we noticed (in the corner of our eye) her use her two fingers pointing from her two eyes toward me as she gestured to the lady who checked us into the motel.
    • We walked down Bridgeport road and spoke about local trout fishing at the fishing shop. He recommended Bodie and Twin Lakes.
    • We had dinner at the Sports bar. Luke had mexican special and two Mammoth IPA beers. Claudia had parmigiana and spaghetti. 
    • Walked back to Bridgeport Inn, Claudia tried the key and it did not work. We walked around the back and it was dark and the door there didn't work either. We returned to the front door and Claudia suggested that I whistle, so I wolf whistled. Coincidently (sarcasm) the young lady who checked us in was just across the road (in dark of a full moon). She came over and we chatted whilst she called someone else for the "right key". About 5 to 10 mins later another lady (perhaps the wife of the owner) arrived with the key and opened the motel. The young lady said she just lived across the road and that the motel was haunted. She said she didn't know the lady with the blonde hair and that apparently the lady with the blonde hair was from out of town and had come with her partner to go to Brodie because the partner wanted to go there. We went to our room. The shower tap lever was missing in the women's toilet. There was no sight of a men's shower at all. The room was upstairs and well presented but there was no power point (only a red plate with no socket). The next morning we discovered that the restrooms were at the other end of the building. The partially opened restroom door had obstructed the signage and caused our confusion.
  • 5 May Tues
    • Breakfast at Bridgeport Inn. Luke only had a coffee, whereas Claudia opted for the free breakfast. 
    • Drove to Bodie via a 16 mile dirt road, saw vultures along the way. Walked around Bodie for a few hours
    • Drove back to Bridgeport and drove to Twin Lakes (turn off was at the North end of Bridgeport and then we continued further for 13 miles). Twin Lakes reminded me of Queenstown, NZ. We had lunch, Luke had a Chili Size burger, Claudia had chips. We saw ducks with ducklings. We walked along part of a hike via a swampy area.
    • Drove to Lake Tahoe via Route 206/207 mountain range and drove around ski resorts at the top. Stopped at Edgewood Golf course for view of sunset
    • Accommodation at Economy Inn for only $45 for queen bed and breakfast included was very good
    • Walked across the road there was a lively young crowd partying with a live band and had Pizza and red wine for dinner.
  • 6 May Wed
    • Drove back to San Francisco. Stopped briefly at Placerville, Coloma, and Auburn on the way.
    • Checked into Europa Hotel (the one in the better part of town) for $70 for queen bed. Dropped off car and Hertz worker gave us a lift back to hotel. Luke went to a Docker Meetup with Joyent at New Relic offices in San Francisco
  • 7 May Thu
    • Driver took us to airport for $30 through hotel and Alaskan airlines put us on earlier fly for leg to Seattle. Had coffee at Beechams at airport.

Sunday, 10 May 2015

Go, Docker, Joyent, and New Relic


Go, Docker, Joyent, and New Relic IN PROGRESS

  • Go Language Installation: 
    • Download and install GoLang installer here
    • Download and install Go Tools to /usr/local/go and include /usr/local/go/bin in PATH env and restart terminal
 $ mkdir $HOME/code/workspace_go
 $ export GOPATH=$HOME/code/workspace_go
 $ export PATH=$PATH:$GOPATH/bin
    • Create Base Path
$ mkdir -p $GOPATH/src/github.com/ltfschoen
    • Create First Program
$ mkdir $GOPATH/src/github.com/ltfschoen/go_test/hello
    • Create hello.go file (ready to use the reverse.go Package dependency)

package main 

import (
"fmt"
"github.com/ltfschoen/go_test/stringutil"
) 

func main() {
fmt.Printf(stringutil.Reverse("!oG ,olleH\n"))
}
    • Build and Run binary to test Go Tool installation success

        $ go install github.com/ltfschoen/go_test/hello

        $ $GOPATH/bin/hello
    • Setup Git Repo

$ cd $GOPATH/src/github.com/ltfschoen/go_test/hello
$ git init
$ git remote add origin git@github.com:ltfschoen/GoTest.git
$ git add --all .
$ git commit -m "Initial commit"
$ git pull origin master
$ git push origin master
    • Write Go library (with Package directory)
$ mkdir $GOPATH/src/github.com/ltfschoen/go_test/stringutil
    • Create Package dependency stringutil reverse.go and test compilation success 
      • Note: 'go install' produces an output file, placing the package object inside the pkg directory of the workspace)
$ go build github.com/ltfschoen/go_test/stringutil
    • Install hello.go program using the Go Tool to install the reverse.go Package and other dependencies
$ go install github.com/ltfschoen/go_test/hello
    • Create reverse_test.go file with functions to be run by the Go Testing Framework and Package and Run Go Test
$ touch $GOPATH/src/github.com/ltfschoen/go_test/stringutil/reverse_test.go$ go test github.com/ltfschoen/go_test/stringutil 

References:
Books
  • 50% READ Docker New Relic Preview Edition
  • 50% READ Programming in Go
  • TODO Orchestrating Docker
  • TODO The Go Programming Language
Events

Sunday, 11 January 2015

JavaScript Design Patterns (Composite, Façade, Adapter)

JavaScript Design Patterns


 Composite Design Pattern 
  • Dfn: 
    • Dynamic User Interfaces achieved by replacing Groups of Objects with a Single Object organised in a Tree Hierarchical Structure in order to leverage functionality such that a Single Command (Function Call) on a Composite Object (Top-Level Parent) that will traverse an entire Nested tree of Collection(s) (composition) of many Sub-Objects and initiate Delegation with the same implementation method / Operation (Complex Behaviour) Recursively to its now independent Loosely Coupled bottom-level Leaf Objects (Leaves do not have Children) whose implementation may be hidden from clients, which provides choice and flexibility in selection of preferred Data Structures used to hold the Children, which may include Arrays, Objects, etc. All Objects within a Composite (including Leaves) must implement and respond to the same Composite Interfaces var ___ = new Interface(___); that must be defined for each Object Class (perhaps using a UML Diagram, accompanied by Duck Typing using Interface , or Type Checking), but Children are not Subclasses and do not Inherit from the Composite. 
  • Application Examples: 
    • Dynamic Input Form with Operations Saving, Restoring, Resetting, Validation, AJAX requests
    • Dynamic Media Gallery with Operations Drag-and-Drop, Hiding, Showing 
  • Usage Approach:
    • Super (Composite) View that has Children (has one or many) that are initially Unknown (Contents and Quantity) Partial (Leaf) Views that may be Grouped into Sets (Composite) of Partials and are potentially Different for each User and Dependent on User Interaction leverages Loosely Coupling:
      • Operations of Inputs is performed Dynamically on the Composite Design Pattern Framework with a Single Command that is called Recursively on all the Composites bottom-level Leaves / Children (not Tightly Coupled to specific input fields) by means of wrapping HTML elements inside JavaScript Objects
      • Additionally Operations and Levels in the Hierarchy may be added to the Modular Composite Interface of the Composite Design Pattern Framework to achieve higher Granularity on Operations that may be called (without affecting existing Object Classes)
  • Benefits: 
    • Loosely Coupled
    • Modular
    • Maintainable
    • Reuse (DRY)
    • Refactorable
  • Warnings: 
    • Cookies should not be used as a Data Structure to Store User Data and Children (Data Validity easily hacked, length restrictions may strip and cause missing data, contained in HTTP Headers of all requests causing performance lag)
    • DOM Nodes should not be used as a Data Structure to Store Children elements to avoid Memory Leaks in browsers caused by necessity for them to maintain reference to their JS wrapper class to implement operations. Use an Array instead.
    • Documentation must highlight the Restrictions that elements cause to the Composite's usefulness, and the Performance Cost each Operation supports, since in large hierarchies the call will still initiate complete traversal to all children in a tree.


 Façade Design Pattern 
  • Dfn: 
    • Organising Pattern that Decouples (Loose Coupling) and conveniently Wraps an Object, changing the Interface it presents to the world by simplifying it and making assumptions (rather than providing extra options like the Adapter Design Pattern) to simplify common and repetitive tasks involved in the process of accessing and modifying complex Classes (contained in an App) and Objects from the Client code (that calls it) in order to save time and maintain Efficiency to meet Demands
    • Utility Libraries
      • Convenience Methods created to increase Flexibility (combining methods) whilst maintaining Granularity (also separately retaining the individual methods that have been combined for convenience) along with ease of interacting (user-friendly presentation of an Object's features) with complex subsystems indirectly, with less likelihood of errors found directly (error checking performed behind the scenes), by combining several existing methods into one
  • Application Examples
    • Shortcut Icons (acts as Facade Interface) navigate deeply nested files and directories
    • Operations on OS GUI (acts as Facade Interface) that indirectly runs commands in background to computer data and functionality 
    • Adding an Event Function (Convenient Methods encapsulates detection code in single location acting as Facade Interface) allows Event Listeners to be added to DOM nodes, by performing cross-browser determination and branching code to detect capabilities and differences between browsers (using Object Detection and Browser Sniffing techniques using Lazy Loading at load time by Abstraction and execution once instead of on every call to speed up the app) with the heavy lifting performed under the hood for implementation of appropriate event listener syntax or event attachment technique to use (reuse hidden low-level code to check against browser differences to avoid repeated manually checking)
    • Abstract cross-browser differences into a Custom Event Utility with Facade Methods that provide a consistent Interface (act as a Facade Interface) to work comfortably (or alternatively with Third-Party Libraries such as Prototype, jQuery, YUI), easily interacting with JS functions built into each Browsers and deal with cross-browser event handling by Batching Utilities into Single Set, and using a Singleton Design Pattern containing Static Methods within a Namespace (Common Methods i.e. getMail, sendMail, archive, or alternatively using a Publish / Subscribe Design Pattern).
    • Wrapper Library or Shims (act as Facade Interface) to help Interface with a Collection of poorly designed APIs by Wrapping them in Single API (with good design)
    • Set Multiple Styles to Multiple HTML Elements' CSS Style Properties at same time by creating a Utility Function (acting as a Facade Interface using the Facade Pattern) to simplify matching HTML Elements and setting CSS Styles in Bulk, whereby we Batch all the HTML Elements and CSS Styles functionality together (under the hood without the client code being aware of the details or being broken by modifications) and trigger it all with just a Single Function Call
    • Error Logging
    • Tracking Page View Stats
  • Benefits: 
    • Loosely Coupled
    • Maintainable
    • Understandable
    • Reuse (DRY)
    • Abstract-Oriented
  • Warnings: 
    • Practicality of Operations must be considered to avoid unnecessary drag by Expensive routines (i.e. a simple task may only need a few simple Facade Functions rather than an entire JS Library)
    • Multiple Constituent Functions may be preferable to a Single Monolithic Facade Function to achieve desired Granularity

 Adapter Design Pattern 
  • Dfn: 
    • Decouples (Loose Coupling) of a Wrapper Object (of the Adapter Design Pattern) Abstraction from its Implementation (enabling independent variation), by using a thin layer of code between incompatible method calls is used to encapsulate an existing Interface that has otherwise Incompatible Classes (which prevents clients from accessing the API) with another different Interface by Migrating and adapting them by reconciling differences in syntax and allowing them to interact together through conversion to bridge differences and achieve Compatibility (it is different from the Facades Design Pattern, as it doesn't remove abilities or simplify the Interface for Convenience sake)
  • Application Examples
    • Interfaces of designed Classes may be Incompatible with Existing APIs. Adapter Design Pattern may be used to allow interaction with the API from these Classes without modifying them directly (and possible breaking them)
    • Existing API Interfaces may change, requiring all client code to be updated to be Compatible with the New Interface. Development of a Client Adapter that implements the New Interface is necessary to survive
    • Adapting between two Libraries by creating two Adaptor Methods to convert the difference between their Interfaces
    • Adapters to create Different Interfaces easier for clients to use
    • Adapter created to access a New API (different Interfaces) instead of an Expensive entire Codebase Rewrite, by Wrapping and handling the logic within a New Interface for an Existing Class without breaking existing implementations
  • Warnings: 
    • Considerations when choosing Set of Utilities for a Library include
      • Impact Determination (Development Suitability)
        • Match with Coding Style of Developers
        • Ease of Implementation
        • Incompatibility with Existing Codebase
      • Interchangeability with Alternative Libraries (Decoupled without requiring changes to Codebase) to improve Performance, Security, Design
      • Compatibility with Intermediary Sets of Adapters during migration from Existing API to New API
      • Expense of an Entire Code Rewrite VS New Adapter Library
    • Consideration when determining between Entire Code (API / Library) Rewrite VS New Adapter Library
      • Extent that Existing API / Library is Standardised
        • Avoid unnecessary development overhead (new set of Utilities that must be supported) of an Adapter when the Existing (Legacy) API or the New Interface proposed to be made compatible are incomplete

References:
  • Chapters 9 - 11, Pro JavaScript Design Patterns by Ross Harmes and Dustin Diaz
Note: Refer to similarities between these JavaScript Design Patterns and the iOS Design Patterns highlighted in one of my previous blog posts

Books
  • 60% Progress Pro JavaScript Design Patterns



Monday, 5 January 2015

Thursday, 1 January 2015

Functional Programming (PureScript)

PureScript Simple DOM (created by Ashley Towns .. and other Open Source contributors)


Important Note: The following was prepared before having read any PureScript books (and only after just having managed to get PureScript Compiler installed thanks to help from Hardy Jones). See below PureScript By Example Git Repo containing working solutions based my application of code samples and custom commentary from the textbook.
  • Link to GitHub Repo here (of the PureScript Simple DOM)
  • Setup
    • Install PureScript  with the commands cabal install cabal-install and cabal install purescript (recommend avoiding having to run 'cabal update', as it breaks GHCi for Haskell), which downloads, builds, configures, and installs:
      • monad-unify-0.2.2
      • pattern-arrows-0.0.2
      • ansi-wl-pprint-0.6.7.1
      • optparse-applicative-0.11.0.1
      • purescript-0.6.2
    • Refer to the following Issue for help I got and Lessons Learnt showing how to install PureScript https://github.com/aktowns/purescript-simple-dom/issues/18
    • Check your current PATH by typing the following in terminal $PATH
    • When you run which cabal it should return the location of the Cabal Executable (i.e. /Users/<your_user_name>/Library/Haskell/bin/cabal)
    • Check where your Cabal Executables are installed by going to the ~/.cabal  cd ~/.cabal directory and inspecting the contents of a where-is-my-stuff.txt File by opening it (i.e. subl where-is-my-stuff.txt).
    • Edit your ~/.bash_profile File (i.e. subl ~/.bash_profile) and add the following line to it to add the directory containing Cabal Executables to the PATH (which will include subdirectories of ~/Library/Haskell/bin as well): export PATH="$HOME/Library/Haskell/bin:$PATH" 
    • Download the latest PureScript Releases and extract it (i.e macos.tar.gz) into the PATH directories) such as ~/Library/Haskell/bin. This will create a subdirectory called /purescript (i.e. ~/Library/Haskell/bin/purescript), which contains the PureScript Compiler executables (allowing you to run commands like psc --help)
    • Finally, reload your current shell by source-ing the ~/.bash_profile with source ~/.bash_profile, which will ensure that when you run cabal --version it returns confirming that the cabal-install version that is installed matches the same version that it built, configured, and installed when you first ran cabal install cabal-install
    • Install and update NPM and Grunt project dependencies npm install -g grunt grunt-init grunt-cli bower and npm update -g grunt grunt-init grunt-cli bower
    • Note that this Grunt project has already been pre-configured with a package.json file and a Gruntfile.js
    • Install Bower dependencies bower install
    • Build with Grunt grunt (uses the Zombie Gem to perform headless Browser testing of the DOM using Node.js)
    • View Grunt commands grunt --help
    • View PureScript Compiler commands  psc --help
    • Try the PureScript Compiler REPL Interface  psci
  • About the Toolkit
    • PureScript Simple DOM is a cross-platform GUI Toolkit (lower level library) wrapper that aims to translate underlying JavaScript API methods into PureScript equivalents to enable imperative-style UI programming using the functional programming paradigm. 
    • PureScript Simple DOM provides an API that may be understood by referring to the Module Documentation (API.md).
    • Since PureScript is a purely functional language (does not support object-orientation or mutable variables without use of IO Actions), the translation is not as simple as translating from JavaScript to another imperative language (using wrappers for marshalling data types and mapping functions and objects), instead the PureScript Simple DOM toolkit wrappers must translate underlying JavaScript API methods into the special Eff Actions that must be caged in the Eff Monad (defined in the PureScript Prelude Module), similar to in Haskell where IO Actions (IO Functions that create IORef wrappers, which represent a pointer to a pure value, enabling event-driven UI callbacks to read and write to the global application state) may be caged in the IO Monad. The Eff Monad handles native effects whilst generating efficient JavaScript.
  • Understanding the GitHub Repo

/bower_components/*  { Bower dependencies installed after running bower install }

/node_modules/*  { Node.js NPM dependencies installed after running npm install }

/outputs/*  { this directory is created as a result of running grunt }

/js/*  { requires Node.js dependencies and called by a Grunt command to run the PureScript tests against the HTML file }

/src/*  { contains individual Safe PureScript Modules (and Unsafe ones too in a subdirectory) that match the API Module Documentation }

/tests/* { contains HTML template and PureScript file that uses QuickCheck to verify that PureScript Simple DOM interacts (read, write) with the Browser Window, HTML Document and Elements.

.bowerrc { generates the defined directory 'bower_components' and installs all bower dependencies in sub-directories after running  bower install }

API.md { 
  • The Module Documentation structure is as follows:
    • AJAX
      • Algebraic Data Types (ADTs) Type Annotation definitions using the data keyword and the :: symbol (compiler infers correct type) (i.e. data <type_constructor> :: <data_constructors> )
      • Function definitions (using currying) in the Type Signatures (i.e. <argument_1> -> <argument_2> -> <argument_3> )
      • Existential Types using the forall keyword to inform the compiler not to care about the type of data from a Type Class, eliminating the need for the type variable 
    • HTML Document
    • HTML Element
    • URI Encoding, Decoding, Parameterization, and JSON Conversion
    • UI Event Handling
    • Web Browser Navigator Info
    • DOM Arrows { Syntactic Sugar that defines Combinators that store DOM Arrow instances of Eff, Maybe, and Just HTML Element ordinary Functions that are applied to Functors (which contain only Values) and extended into Applicative Functors. Note: Arrows define computations that may be Chained. Monads are a computational strategy that define a container for chainable Eff Functions (Actions) and are a subset of Arrows }
    • Web Browser DOM Component Types
    • Unsafe AJAX
    • Unsafe HTML Document
    • Unsafe HTML Element
    • Unsafe UI Event Handling
    • Unsafe Web Browser Navigator Info
    • Unsafe DOM Arrows 
    • Unsafe Utilities
    • Unsafe Web Browser Window Attributes
}

bower.json { bower.json is a manifest of metadata for Bower that includes Package definitions and dependencies for development and production environments. The following command bower install is run from a terminal to install:

  • purescript-foldable-traversable#0.1.6 bower_components/purescript-foldable-traversable
    • ├── purescript-arrays#0.3.0
    • ├── purescript-control#0.2.1
    • ├── purescript-either#0.1.4
    • ├── purescript-maybe#0.2.1
    • ├── purescript-monoid#0.1.5
    • └── purescript-tuples#0.2.3
  • purescript-strings#0.4.2 bower_components/purescript-strings
    • └── purescript-maybe#0.2.1
  • purescript-math#0.1.0 bower_components/purescript-math
  • purescript-quickcheck#0.3.2 bower_components/purescript-quickcheck
    • ├── purescript-arrays#0.3.0
    • ├── purescript-either#0.1.4
    • ├── purescript-exceptions#0.2.2
    • ├── purescript-foldable-traversable#0.1.6
    • ├── purescript-math#0.1.0
    • ├── purescript-maybe#0.2.1
    • ├── purescript-random#0.1.1
    • ├── purescript-strings#0.4.2
    • └── purescript-tuples#0.2.3
  • purescript-sets#0.1.1 bower_components/purescript-sets
    • ├── purescript-arrays#0.3.0
    • ├── purescript-foldable-traversable#0.1.6
    • ├── purescript-maps#0.1.5
    • ├── purescript-maybe#0.2.1
    • └── purescript-tuples#0.2.3
  • purescript-tuples#0.2.3 bower_components/purescript-tuples
    • ├── purescript-arrays#0.3.0
    • ├── purescript-control#0.2.1
    • └── purescript-monoid#0.1.5
  • purescript-maybe#0.2.1 bower_components/purescript-maybe
    • └── purescript-control#0.2.1
  • purescript-arrays#0.3.0 bower_components/purescript-arrays
    • ├── purescript-control#0.2.1
    • └── purescript-maybe#0.2.1
  • purescript-random#0.1.1 bower_components/purescript-random
  • purescript-exceptions#0.2.2 bower_components/purescript-exceptions
  • purescript-control#0.2.1 bower_components/purescript-control
  • purescript-either#0.1.4 bower_components/purescript-either
    • └── purescript-control#0.2.1
  • purescript-monoid#0.1.5 bower_components/purescript-monoid
    • ├── purescript-arrays#0.3.0
    • └── purescript-maybe#0.2.1
  • purescript-maps#0.1.5 bower_components/purescript-maps
    • ├── purescript-arrays#0.3.0
    • ├── purescript-foldable-traversable#0.1.6
    • ├── purescript-math#0.1.0
    • ├── purescript-maybe#0.2.1
    • ├── purescript-strings#0.4.2
    • └── purescript-tuples#0.2.3
 }

Gruntfile.js { PureScript Simple DOM is a Grunt project that uses Gruntfile.js to configure tasks. When run with the command grunt, it checks that Grunt is installed locally using the Node.js require() system, and if it is found then the Grunt CLI loads the local installation of the Grunt library, and applies and executes the tasks that have been configured in the Gruntfile.js. 
The Grunt "wrapper" function module.exports = function(grunt) { currently passes configuration data to the grunt.initConfig method

Custom project-specific tasks are defined in external .js files and loaded using the grunt.loadNpmTasks method, including: 

  • grunt-contrib-copy
  • grunt-contrib-clean
  • grunt-execute
  • grunt-purescript


The Gruntfile is currently configured so that when:
  • grunt or grunt default is run, it Registers the Tasks:
    • clean
    • make
    • test
  • grunt test is run, it Registers the Tasks:
    • pscMake:tests
    • copy
    • execute:tests  
  • grunt make is run, it Registers the Tasks:
    • pscMake:lib
    • docgen
    • dotPsci (creates a .psci file)
When I first ran grunt errors were encountered, prompting me to raise this Issue on GitHub (initially because I couldn't get PureScript in my PATH, but now this is resolved and psc commands are recognised). To get all the tests to pass, just comment out the final 'userAgent' test on Line 122 (i.e. replace Line 122 with   -- userAgent navigator >>= (\name -> quickCheck' 1 $ name == "Mozilla/5.0 Chrome/10.0.613.0 Safari/534.15 Zombie.js/2.0.0-alpha31")). Currently I'm trying to figure out why replacing the userAgent value with the userAgent value that is found when using Chrome Dev Tools, running ```self```, and expanding the Window object (i.e. Window > clientInformation > userAgent) 





.psci { configuration file for the interactive mode of the PureScript PSC Compiler, which is generated when grunt make command is run  }

package.json { package.json is a manifest of metadata for this Grunt project that installs the Modules and associated Dependencies from the /node_modules/ directory when the Node.js Package Manager command npm install is run from a terminal. The output installs:
  • ws@0.6.4  node_modules/zombie/node_modules/ws
  • contextify@0.1.11 node_modules/zombie/node_modules/jsdom/node_modules/contextify
  • grunt-contrib-copy@0.5.0 node_modules/grunt-contrib-copy (Copy files and folders)
  • grunt-purescript@0.5.3 node_modules/grunt-purescript
  • grunt-execute@0.1.5 node_modules/grunt-execute
  • grunt-contrib-clean@0.5.0 node_modules/grunt-contrib-clean (Cleans files and folders)
    • └── rimraf@2.2.8
  • grunt@0.4.5 node_modules/grunt
    • ├── which@1.0.8
    • ├── dateformat@1.0.2-1.2.3
    • ├── eventemitter2@0.4.14
    • ├── getobject@0.1.0
    • ├── colors@0.6.2
    • ├── rimraf@2.2.8
    • ├── async@0.1.22
    • ├── hooker@0.2.3
    • ├── grunt-legacy-util@0.2.0
    • ├── exit@0.1.2
    • ├── nopt@1.0.10 (abbrev@1.0.5)
    • ├── lodash@0.9.2
    • ├── coffee-script@1.3.3
    • ├── glob@3.1.21 (inherits@1.0.0, graceful-fs@1.2.3)
    • ├── minimatch@0.2.14 (sigmund@1.0.0, lru-cache@2.5.0)
    • ├── underscore.string@2.2.1
    • ├── iconv-lite@0.2.11
    • ├── findup-sync@0.1.3 (glob@3.2.11, lodash@2.4.1)
    • ├── grunt-legacy-log@0.1.1 (underscore.string@2.3.3, lodash@2.4.1)
    • └── js-yaml@2.0.5 (esprima@1.0.4, argparse@0.1.16)
  • zombie@2.5.1 node_modules/zombie
    • ├── ms@0.7.0
    • ├── lazybird@1.0.0
    • ├── mime@1.2.11
    • ├── debug@2.1.1 (ms@0.6.2)
    • ├── iconv-lite@0.4.5
    • ├── tough-cookie@0.12.1 (punycode@1.3.2)
    • ├── eventsource@0.1.4 (original@0.0.5)
    • ├── bluebird@2.5.3
    • ├── request@2.51.0 (caseless@0.8.0, aws-sign2@0.5.0, json-stringify-safe@5.0.0, forever-agent@0.5.2, tunnel-agent@0.4.0, stringstream@0.0.4, oauth-sign@0.5.0, qs@2.3.3, node-uuid@1.4.2, mime-types@1.0.2, combined-stream@0.0.7, form-data@0.2.0, http-signature@0.10.0, bl@0.9.3, hawk@1.1.1)
    • ├── ws@0.6.4 (options@0.0.6, ultron@1.0.1, nan@1.4.1)
    • └── jsdom@1.4.0 (browser-request@0.3.3, xmlhttprequest@1.6.0, cssom@0.3.0, nwmatcher@1.3.3, parse5@1.3.0, htmlparser2@3.8.2, cssstyle@0.2.22, contextify@0.1.11)
}



PureScript By Example (created by Luke Schoen)



Sublime Text 2 Plugin for PureScript (created by Hardy Jones)

Link to GitHub Repo here

Setup
  • Copy the Git Repo into a new sub-directory in the Sublime Text 2 Packages directory 
    • cd ~/Library/Application\ Support/Sublime\ Text\ 2/Packages
    • git clone https://github.com/joneshf/sublime-purescript
  • Restart Sublime Text 2
PureScript Syntax Highlighting & Code Snippets
  • After Setup, go to Sublime Text 2 menu 
    • View > Syntax > PureScript
  • Enter a Code Snippet keyword (until "instance      instance" appears in the Drop-Down) and then select "instance      instance" (using Up/Down Keys) and then Press Tab and PureScript "instance" code block template will auto-populate (i.e. for example, the 'instance' keyword may be used, as it is contained between the <tabTrigger></tagTrigger> tags of the /Snippets/instance.sublime-snippet file) )

    Reference Documentation (Sublime Text 2 Plugins) 


    Events
    •  ATTENDING Ruby Conference (RubyConf) (Melbourne, 4 - 7th Feb 2015)
      • 7pm, Wed 4 Feb, Opening Party, Trunk Bar & Restaurant, 275 Exhibition St, Melbourne
      • 4:30pm, Sat 7th Feb, Family Picnic, Flagstaff Gardens, Corner of Williams St & La Trobe St, Melbourne
      • 8pm, Sat 7th Feb, After Party, City of Melbourne Bowling Club, Within Flagstaff Gardens near Dudley St, Melbourne

    Books
    • 20% Progress Developing Web Applications with Haskell and Yesod
    • 20% Progress Graphical User Interfaces in Haskell (by Gideon Sireling)
    • Pending UML for Java Programmers
    • TODO PureScript by Example (LeanPub)

    Links

    IN PROGRESS (NOT WORKING) Deploying Haskell on Heroku