ted.neward@newardassociates.com | Blog: http://blogs.newardassociates.com | Github: tedneward | LinkedIn: tedneward
What the h3ll is "polytechnical careering"?
verb, to manage one's career
(in this case, one's technology-related career)
Being a combination of a variety of things, on a variety of things, in technology
polyglot: multiple languages
polypraeclusio: multiple storages
polycrepido: multiple platforms (foundations)
... you see the value in different technologies
... you don't believe in "just one" anything
... or in "one size fits all" solutions
... you embrace the idea of mixing-and-matching
... you find yourself identifying with Karl Marx:
"From each technology, according to its abilities, to each project, according to its needs"
The world has always been a polyglot one
The *nix world settled on a "C" standard
so long as you could set up a C stack frame, you could call me and/or vice versa
hence the need for "extern 'C'" in C++
This allowed a degree of interoperability
and that in turn has allowed tools to focus
IF programmers were to reach outside of their one tool
The world has always been a polyglot one
With the introduction of the Web, this became more obvious
HTML, CSS, JavaScript on the front end
XML for configuration and/or data exchange (WS-*)
SQL for data storage
... plus whatever implementation language you chose
The world has always been a polyglot one
The JVM pioneered "one platform, many languages"
The JVM enters the mainstream in 1995
1996: "alternative languages" for the JVM emerge: Pizza, Kawa, others
2001: AspectJ makes its debut
2003: James Strachan thinks out loud about a Ruby+Java: Groovy is born
The CLR followed suit shortly thereafter
C#, VisualBasic.NET, C++/CLI shipped with 1.0
Boo, Nemerle, others emerged (Project7)
F# came as part of .NET 3.0
The world has always been a polyglot one
With the introduction of the Modern Web Platform, it's insanely obvious
HTTP APIs are abstracting away the implementation platforms
Microservices are reducing the surface area of the APIs
Cloud services are reducing the scope of the problem
All the Web, plus JSON across the HTTP links
Requirements for polyglot:
a common communication medium
shared memory or operating system channel
communication channel (a la HTTP over TCP/IP)
a common data frame format
C-style stack frame
SOAP
JSON
a common identifiers/metadata format
(ideally) some common discovery/reflection process/API
"Many storages"
there's more than one way to store a value
we sort of knew this
... but then we forgot
In the beginning, God invented the relational database...
actually, no, IBM did
or, rather, Dr E.F. ("Ted") Codd did
"Derivability, Redundancy, and Consistency of Relations Stored in Large Data Banks", IBM Research Report RJ599 (August 19th, 1969)
backed by a set-oriented mathematical model
and with a "user-friendly" query language (SQL)
Relational model challenged data store systems at the time
TOTAL, IDS, IMS, and others
these usually had their own storage format
and their own (completely unique) means of access
... driven entirely by code
but it was not until Oracle "took over the world" that we finally got a unified data store model!
... and what a wonderful world that was, was it not?
But along came the Internet...
... and HTML
... and a desire to mark up data
... which was called XML...
... and suddenly Pandora's Box was open again
With the advent of the Web, we changed our enterprise apps
Before, enterprise apps were internal
Known user base, known loads, known scale
This user base was not likely to change without huge warning
With the Web app, we began to project our enterprise apps out into the Internet
This meant an unknown and unpredictable user base
With that came an unknown and unpredictable load and scale
The problem is one of load/scale and contention
"Each node in a system should be able to make decisions purely based on local state. If you need to do something under high load with failures occurring and you need to reach agreement, you've lost." --Werner Vogels, CTO, Amazon
The problem is one of load/scale and contention
Repeat after me: Contention is the enemy of scalability
And scale is the issue of the Internet
CAP Theorem
Consistency: all database clients see the same data, even with concurrent updates
Availability: all database clients are able to access some version of the data
Partition Tolerance: the database can be split over multiple servers
"Pick two"
RDBMS goes for C + A
Most "NoSQL" databases go for A + P
What do we mean by a 'platform'?
"a major piece of software, as an operating system, an operating environment, or a database, under which various smaller application programs can be designed to run."
http://www.dictionary.com/browse/software-platform
In the beginning, God invented... um...
there's never really been a universal platform
unless you maybe count Windows on the desktop
platforms have grown beyond just the OS
Many, many platforms exist today
Desktop: Windows, Mac OS, Linux
Server: Linux (flavors), Windows
Containers
Mobile: Android, iOS
Cloud: Amazon, Azure, GCP
Verticals: Office, GSuite
Vendor: Salesforce/Force.com, Facebook
Requirements for polycrepido:
a common communication medium
a common data frame format
SOAP
JSON
a common identifiers/metadata format
Polytechnical approaches come with costs
increased complexity
multiple languages means more the developer has to know
who has time to learn all of these all that deeply?
"jack of all trades, master of none"
interoperability issues
conflicting approaches
Consider the following scenarios:
logic changes routinely/regularly
problems are complex permutations of possibilities
logic is best expressed by domain experts
requirements don't fit one particular paradigm
... or stretch across multiple paradigms
implementation: objects, operations, etc
storage: tables, documents, graphs, etc
disparate team with wide range (and no unity) of skills
Solution: from each tool... to each problem...
Logic changes routinely
IT is too slow to respond to user requests
users want to change logic on non-sprint cycles
users want to change logic without involving IT
Solution: Scripting engines/languages
Groovy, JRuby, Jython, ...
Problems are complex permutations of possibility
multiple variables collide in different ways, creating deep possibility trees
logic for individual components/rules easily declared
example: Sudoku
Solution: Logic engines/languages
Prolog, JESS
Logic is best expressed by domain experts
attempting to translate is a bad game of "operator"
debugging needs to be done by domain experts; developers can't
domain logic is (somewhat) independent of its representation
Solution: Domain-specific languages (DSLs)
Requirements don't fit one particular paradigm
some data will fit naturally into relationships
some data will need to connect to other data and track the connections
some data will be large binary objects that cannot be indexed easily
some data will need to be categorized on the fly
example: YouTube
Solution: Multiple storage tools/tiers/engines
Disparate team with wide range of skills
... and absolutely no common unity of skillset
developers have deep knowledge in their respective areas
training to unify the skillset will take way too long/cost way too much
Solution: Embrace the polytechnical
"It could never work"
Tell that to the Republicans
Obama's 2012 Election IT Team
"4Gb/s, 10k requests per second, 2,000 nodes, 3 datacenters, 180TB and 8.5 billion requests. Design, deploy, dismantle in 583 days to elect the President."
source: https://blog.appfog.com/what-the-obama-it-team-teaches-us-about-polyglot-programming/
Consider the Haskell concept of a list
let numbers = [ 1, 2, 3 ]
We can do a few things with a list
let headOfList = head numbers print headOfList {- 1 -} let lastNumber = last numbers print lastNumber {- 3 -} let tailOfList = tail numbers print tailOfList {- [2, 3] -} let takeSomeOfList = take 2 numbers print takeSomeOfList {- [1, 2] -}
We can create a list out of a range of values
let numberRange = [1..100] print numberRange {- [1, 2, 3, ... , 99, 100] -} let evens = [2, 4..100] print evens {- [2, 4, 6, ... , 98, 100] -}
We can create a list out of code
let otherEvens = [x | x <- [1..10]] print otherEvens let squares = [x*x | x <- [1..10]] print squares let fizzBuzz = [ if x `mod` 5 == 0 then "BUZZFIZZ" else if x `mod` 3 == 0 then "BUZZ" else if x `mod` 4 == 0 then "FIZZ" else show x | x <- [1..25]] print fizzBuzz
We can even create an infinite list
let forever = [1..] {- printing forever is a bad idea.... -} let foreverLove = cycle ["LOVE"] print $ take 3 foreverLove {- ["LOVE", "LOVE", "LOVE"] -}
What a silly idea... Infinite lists
I mean, who ever would have a collection that goes on forever?
What kind of list goes on forever?
Haskell calls these infinite lists "streams", by the way
What if we had a Java Iterator... without a Collection?
An "evens" for-comprehension, in Java
class EvensToAHundredComprehensionIterator implements Iterable<Integer> { public Iterator<Integer> iterator() { return new Iterator<Integer>() { int count = 0; public boolean hasNext() { return count <= 100; } public Integer next() { if (count % 2 == 0) return count++; else { count++; return next(); } } public void remove() { } }; } }
Using it in Java
for (int val : new EvensToAHundredComprehensionIterator()) { System.out.print(val + ".."); } System.out.println();
How about an Iterator that knows how to read a file?
class FileIterator implements Iterable<String> { BufferedReader br; private FileIterator(BufferedReader br) { this.br = br; } public static FileIterator open(String filename) throws IOException { FileReader fr = new FileReader(filename); BufferedReader br = new BufferedReader(fr); return new FileIterator(br); }
How about an Iterator that knows how to read a file?
public Iterator<String> iterator() { Iterator<String> ret = new Iterator<String>() { String line = null; public boolean hasNext() { return line != null; } public String next() { String result = line; try { line = br.readLine(); } catch (IOException ioEx) { line = null; } return result; } public void remove() { } }; ret.next(); return ret; } }
How about an Iterator that knows how to read a file?
for (String line : FileIterator.open("./ItWithoutColl.java")) { System.out.println("FOUND>>> " + line); }
Gong down this path leads you to a number of interesting things... some of which were captured in Guava
Iterables
Iterators
... and some of which were captured in Java8
java.util.stream.*
first-class functions ("lambdas"/function literals syntax)
But think about infinite streams again for a second
But think about infinite streams again for a second
... what if we think about external events as streams?
user input
push notifications from the server
timer events
... and our responses to those events as functions?
in other words, putting some code around "take"ing one incoming atom at a time, processing it, and moving on to the next (if it's available)
Congratulations
Congratulations
... for you have just taken your first steps to understanding
Functional programming
Functional reactive programming
Reactive architectures
Redux
... and a few more things
embrace an aggressive plan of self-education
embrace an aggressive plan of self-education
formulate a personal ontology for technology
embrace an aggressive plan of self-education
formulate a personal ontology for technology
pursue dissimilar angles
embrace an aggressive plan of self-education
formulate a personal ontology for technology
pursue dissimilar angles
create your own 'evaluation function' for new tech
embrace an aggressive plan of self-education
formulate a personal ontology for technology
pursue dissimilar angles
create your own 'evaluation function' for new tech
don't be afraid to turn away
embrace polytechnical employees; encourage them
embrace polytechnical employees; encourage them
make education a formal part of their employment
establish formal dissent
embrace polytechnical employees; encourage them
make education a formal part of their employment
establish formal dissent/"loyal opposition"
avoid groupthink by actively working against it
set non-business technical goals and constraints
embrace polytechnical employees; encourage them
make education a formal part of their employment
establish formal dissent/"loyal opposition"
avoid groupthink by actively working against it
set non-business technical goals and constraints
create the framework for making good decisions
discover what is "core business" and what isn't
embrace polytechnical employees; encourage them
make education a formal part of their employment
establish formal dissent/"loyal opposition"
avoid groupthink by actively working against it
set non-business technical goals and constraints
create the framework for making good decisions
discover what is "core business" and what isn't
create the framework for making good decisions
accept that not all members are "the same"
embrace polytechnical employees; encourage them
make education a formal part of their employment
establish formal dissent/"loyal opposition"
avoid groupthink by actively working against it
set non-business technical goals and constraints
create the framework for making good decisions
discover what is "core business" and what isn't
create the framework for making good decisions
accept that not all members are "the same"
different skillsets, different perspectives means different tools
Polytechnical careerism is not easy
it requires investment and constant care/feeding
you may catch flak from those around you
your "brand" will often not transfer across technical spaces
But if it were easy, anybody would do it