<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
> <channel><title>ShiftForward - online advertising technology r&#38;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</title> <atom:link href="http://www.shiftforward.eu/feed/" rel="self" type="application/rss+xml" /><link>http://www.shiftforward.eu</link> <description>ShiftForward - online advertising technology r&#38;d</description> <lastBuildDate>Thu, 28 Mar 2013 17:41:04 +0000</lastBuildDate> <language>en-US</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.5.1</generator> <item><title>Why (Post-)Functional Programming Matters</title><link>http://www.shiftforward.eu/techtalks/2013/03/why-post-functional-programming-matters/</link> <comments>http://www.shiftforward.eu/techtalks/2013/03/why-post-functional-programming-matters/#comments</comments> <pubDate>Thu, 28 Mar 2013 16:06:11 +0000</pubDate> <dc:creator>ShiftForward</dc:creator> <category><![CDATA[Tech Talks]]></category> <category><![CDATA[functional programming]]></category> <category><![CDATA[scala]]></category> <guid
isPermaLink="false">http://www.shiftforward.eu/?p=784</guid> <description><![CDATA[<p>ShiftForward&#8217;s CTO Hugo Ferreira about functional programming&#8217;s place in today&#8217;s ad technology engineering for high-performance and scalable systems. Why (Post-)Functional Programming Matters &#8220;The limits of my language mean the limits of my world.&#8221; &#8211; Ludwig Wittgenstein Computer (and computing) science (CS) is a very peculiar field of research when compared to other sciences, particularly concerning [...]</p><p>The post <a
href="http://www.shiftforward.eu/techtalks/2013/03/why-post-functional-programming-matters/">Why (Post-)Functional Programming Matters</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></description> <content:encoded><![CDATA[<p>ShiftForward&#8217;s CTO <a
href="http://www.shiftforward.eu/who-is-shiftforward/" title="Who">Hugo Ferreira</a> about functional programming&#8217;s place in today&#8217;s ad technology engineering for high-performance and scalable systems.</p><h1 id="whypost-functionalprogrammingmatters">Why (Post-)Functional Programming Matters</h1><p>&#8220;<em>The limits of my language mean the limits of my world.</em>&#8221; &#8211; Ludwig Wittgenstein</p><p>Computer (and computing) science (CS) is a very peculiar field of research when compared to other sciences, particularly concerning themes such as <em>software engineering</em> and <em>system&#8217;s architecture</em>. For starters, it has little more than 80 years, which puts it into an interesting proposition when compared to Physics or Mathematics: having a &#8220;conversation&#8221; with key personalities is not that unrealistic. Unlike Aristotle, Isaac Newton or Albert Einstein, many of the &#8220;genius&#8221; behind computer science are still living among us; a gentle evidence of its youth.</p><p>On the other hand, the liberal use of the term &#8220;science&#8221; (even <em>engineering</em> as in <em>computing engineering</em>), makes our Physics friends flinch at our day-to-day methodology. We don&#8217;t calculate programs. We don&#8217;t derive implementations. And when something goes wrong, our assessment method is so empirical that it would be equivalent to building a copy of the failed bridge, and observe bolt by bolt &#8211; with intuition (and stack dumps) guiding which bolts to observe first &#8211; hoping to find the one that fails. This arguable &#8220;lack of scientific rigour&#8221; is well reflected when Donald Knuth wrote one of the most rigorous treatises on computer science, and decided to call it &#8220;<em>The Art of Computer Programming</em>&#8221; <a
href="#fn:1" id="fnref:1" title="see footnote" class="footnote">[1]</a>.</p><p>But this constant attitude towards the synthesis of programs doesn&#8217;t mean that development cannot be made more <em>rigorous</em> <a
href="#fn:2" id="fnref:2" title="see footnote" class="footnote">[2]</a>, or at least more <em>scientific</em> or <em>closer to the exact sciences</em>. The hacker way of <em>coding first, asking questions later</em> is more due to the <em>attractiveness</em> of computers as a <em>creation tool</em> than to any inherent property (or limitation) of the field. Researchers and professionals of the so called <em>critical systems</em> had demonstrated this possibility years ago, with the aid of <em>formal methods</em> <a
href="#fn:3" id="fnref:3" title="see footnote" class="footnote">[3]</a>. Much of this research builds upon a rigorous abstraction of <em>computability</em> and <em>language</em>, and is known as Lambda Calculus. Formalized circa 1930, it has enabled the research on the behaviour of computational systems, the creation of predictive models of its properties, and to uncover high-level patterns of computation that abstract irrelevant details and empower the creation of even more complex systems. That&#8217;s what happens when you use mathematics, and that&#8217;s what makes a science&#8230; well&#8230; <em>scientific</em>; much more important than the capability of explaining current observations, is the ability to &#8220;predict&#8221; yet unobserved phenomena.</p><p>But we don&#8217;t need to go into &#8220;heavy&#8221; formal systems, such as Coq or Isabelle, to reap the benefits of mathematics, and still have a practical framework to build and deploy products <a
href="#fn:4" id="fnref:4" title="see footnote" class="footnote">[4]</a>. In fact, the 1950s gave us such tool: LISP <a
href="#fn:5" id="fnref:5" title="see footnote" class="footnote">[5]</a>.</p><p>Notwithstanding, most of the tools that we use today are not LISP based. But most are C based, and despite the fundamental differences Alan Kay introduced with Object-Oriented languages, they are (still) an imperative variant. And with imperative languages, any relation between the math behind the problem, and the implementation artefacts (source-code), is the sole responsibility of the developer. We know the mathematical model behind the QuickSort algorithm, and of the binary search in a list. But none of these relations &#8220;emerge&#8221; when we contemplate (or glance) at its source-code in C. It is, in its most fundamental sense, a list of commands that a system &#8220;rigorously&#8221; obeys <a
href="#fn:6" id="fnref:6" title="see footnote" class="footnote">[6]</a>, though it represents an extremely close model of what the CPU is doing, and as such it has enjoyed outstanding run-time performance and massive adoption <a
href="#fn:7" id="fnref:7" title="see footnote" class="footnote">[7]</a>.</p><p>On the other end of the spectrum there are the LISP (and ML) variants and other Lambda-Calculus inspirations. This isn&#8217;t about a mere syntactic preference, favouring parenthesis <code>()</code> over brackets <code>{}</code>. This is about a fundamentally different perspective, where programs no longer manipulate <em>memory</em> nor define their own <em>flux</em>, but are more regarded as algebraic equivalences and substitution of symbols, where <em>memory</em> and <em>flux</em> are implementation details of the machine. These languages are called <em>functional</em> because they focus on <em>verbs</em>, on functions and composition; <em>mathematical</em> functions as <em>transformations</em> and <em>relations</em>, in contrast to imperative languages that focus on <em>nouns</em>, on things, what they are, and their corresponding capabilities.</p><p>But discussing programming languages is hard&#8230; We know that people tend to <em>defend</em> their choices by considering language criticism a personal attack on themselves, and stay inside their comfort zone. Discussing programming paradigms is even more difficult; the typical Java developer may be opinionated about C#, but it will probably be very defensive against&#8230; say&#8230; Erlang or Haskell. Endless discussions over parenthesis or commas will spring to life. Code readability (whatever that is) will be summoned. Even the categories of <em>average programmers</em> and <em>real-world programs</em> will be promptly accepted as axiomatic facts of daily programming. Irony and sarcasm will reign, such as the recent dichotomy of programming being either &#8220;math&#8221; or &#8220;interpretative dance&#8221; <a
href="#fn:8" id="fnref:8" title="see footnote" class="footnote">[8]</a>.</p><p>So why give a 60 year old concept any importance? The above was tried and claimed years ago, and yet, imperative (and OO) languages are now the norm. Perhaps once we understand what Functional Programming enables us to do today (instead of discussing semantics over what it is), we will come to understand what Paul Graham once said:</p><p>&#8220;<em>&#8230; the short explanation of why this 1950s language is not obsolete is that it was not technology but math, and math doesn&#8217;t get stale. The right thing to compare Lisp to is not 1950s hardware, but, say, the Quicksort algorithm, which was discovered in 1960 and is still the fastest general-purpose sort.</em>&#8221;</p><p>So, without much ado, here&#8217;s the top 5 reasons <em>Why (Post-)Functional Programming Matters</em> for the ad-tech companies <a
href="#fn:9" id="fnref:9" title="see footnote" class="footnote">[9]</a>:</p><h3 id="reasonn.5theyscale">Reason N. 5 They scale!</h3><p><em>&#8220;The way the processor industry is going, is to add more and more cores, but nobody knows how to program those things. I mean, two, yeah; four, not really; eight, forget it.&#8221;</em> &#8211; Steve Jobs</p><p>Pick a software architect &#8211; any architect that has drawn large-scale software systems &#8212; and ask her about design and architectural patterns, say <em>Pipes and Filters</em>, <em>Client-Server</em> or the <em>Observer</em> pattern; she&#8217;ll undoubtedly tell you is that they are now accepted as an invaluable tool to create, communicate and document the orchestration among the myriad of components in a large system. The legacy we inherited from Gamma <em>et al.</em>, heavily inspired in the works of Christopher Alexander <a
href="#fn:10" id="fnref:10" title="see footnote" class="footnote">[10]</a>, goes well beyond the mere catalogue of recurrent designs. It gives us a framework to capture and systematize empirical knowledge, to uncover new relations and to think at higher levels of abstraction.</p><p>But these &#8220;classic&#8221; patterns lack something of a greater value too: they lack the mathematical formalism that allows one to <em>reason</em> about their structure and their interactions <a
href="#fn:11" id="fnref:11" title="see footnote" class="footnote">[11]</a>. Let me tempt you with an example. Consider both the set of natural numbers and an operation (such as sum) over them; there are a lot of <em>properties</em> about the sum. First, sum is an endofunction, which is a funny way to say that if you sum two natural numbers, you get a natural number as a result. It also has the so called <em>neutral</em> element: if you sum something with zero, you get back the same number. Sum is also an associative operation; <code>(1+2)+3</code> is equivalent to <code>1+(2+3)</code>. These properties &#8211; an associative endofunction with an identity &#8211; form what is known as a <em>monoid</em> <a
href="#fn:12" id="fnref:12" title="see footnote" class="footnote">[12]</a>.</p><p>There are endless monoids over endless types of structures. String concatenation, for example, form a <em>monoid over strings</em> (with the identity being the empty string). One can simply regard the fancy name <em>monoid</em> as a &#8220;pattern&#8221; of structures; but a different type of pattern in the sense that it is strictly defined <a
href="#fn:13" id="fnref:13" title="see footnote" class="footnote">[13]</a>.</p><p>Now your question should be: what does this matter to me, or to the construction of advertising systems? Very simple. Monoids (being associative) enjoy a very interesting property: they scale! Because <code>(a+b+c+d)</code> is the same thing as <code>(a+b)+(c+d)</code>, you can send the first part <code>(a+b)</code> to a machine, and the second part <code>(c+d)</code> to another machine. The two operations can then execute in parallel, and their result can be merged by yet another machine <a
href="#fn:14" id="fnref:14" title="see footnote" class="footnote">[14]</a>. This is very close to the fundamental ideas beyond the <em>mapreduce</em> model, recently popularized by Google&#8217;s implementation, and as you can see, you don&#8217;t really need to rely on such specific technologies to reap the same benefits <a
href="#fn:15" id="fnref:15" title="see footnote" class="footnote">[15]</a>.</p><p>So Functional Programming scales, because it allows the programmer to scale. It brings a multitude of powerful abstractions, which not only avoids re-inventing the wheel, but allows a more &#8220;precise&#8221; reasoning over programs, its properties and their resulting quality.</p><h3 id="reasonn.4theyreallyscale">Reason N. 4 They really scale!</h3><p>&#8220;<em>The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time.</em>&#8221; &#8211; Tim Cargill</p><p>Software is more than just writing code. It&#8217;s debugging code! And there&#8217;s a root to all evil when it comes to debugging: <em>mutability</em>. I once spent hours of trying understand why a certain program ceased to function if I executed it step-by-step, but worked OK if I just jumped over the function. The problem? The debugger window was displaying the local variables and some good, well-intended soul, decided to override a getter to cache the result. And that specific getter function was crashing the application.</p><p>But there&#8217;s more&#8230; If we never know when objects will change, we can&#8217;t possibly know if removing an apparent superfluous call, or changing the order of execution, will output the same behaviour <a
href="#fn:16" id="fnref:16" title="see footnote" class="footnote">[16]</a>. We&#8217;ve all seen this taken to the extreme in dynamic languages such as JavaScript. Undefined functions and fields springing to life, because some previous call defined and re-defined them. A living hell to debug. <a
href="#fn:17" id="fnref:17" title="see footnote" class="footnote">[17]</a></p><p>Functional Programming scales, because it gives better guarantees about the behaviour of your programs. They are easier to test, because they are more &#8220;isolated&#8221; in a certain sense. But much more important it empowers safer redesign and re-factoring; it makes program more resilient to change!</p><h3 id="reasonn.3theyscaleevenifyoudonothingaboutit">Reason N. 3 They scale even if you do nothing about it!</h3><p><em>&#8220;A programming language is low level when its programs require attention to the irrelevant.&#8221;</em> &#8211; Alan J. Perlis.</p><p>Now imagine if pieces of programs could be regarded as <em>pure</em>, i.e., having absolutely no side effects. What would this mean?</p><p>If parts of a program are pure, then one can rearrange the order of their execution. They won&#8217;t rely on any context, besides the parameters one passes to them. This key idea of FP is called &#8220;referential transparency&#8221;; functions do not behave differently the second time you look at them: you give the same inputs, you get the same result. A trivial idea with profound implications, because if there&#8217;s absolute guarantee that changing the order of execution will produce the same results, then one gains scalability for free, by, for example, executing different parts of the program in different threads or machines.</p><p>But there&#8217;s more to purity than inherent parallelization; things that <em>really pure™</em> functional languages <a
href="#fn:18" id="fnref:18" title="see footnote" class="footnote">[18]</a> take advantage of: <em>laziness</em> and <em>memoization</em>. Avoiding the risk to incur in a large technical debate over the advantages and disadvantages of such techniques, let us just state what they <em>provide</em>, and leave to the reader the decision over their suitability for the ad-tech industry.</p><p>Laziness and memoization could be translated to two obvious principles: &#8220;<em>don&#8217;t compute something until you need it</em>&#8221; and &#8220;<em>don&#8217;t recompute something you have computed before</em>&#8221;. Though trivial principles, the programmer usually has to be aware of them throughout the code; here&#8217;s a list, multiply the elements by two, give me the first one. Wait&#8230; why don&#8217;t I just take the first one, and multiply it by two?</p><p>And what about loading a webpage? Show me the first article (written in markdown); translate it to HTML. Show me again the first article; translate it again&#8230; A thousand of users requesting to view the first article; a thousand of translations of exactly the same content. Hmmm&#8230; Maybe we should once and for all translate the first article and store it somewhere? Let&#8217;s throw in a cache.</p><p>Suffice to say that FP &#8211; particularly due to the principle of &#8220;referential transparency&#8221; &#8211; provides the ability to tackle those concerns at the compiler level. A sufficiently advanced compiler can even achieve much of that for us&#8230; automatically; it may not throw in a cache, but it will easily memoize the results of a function whose parameters are <em>always the same</em>. FP scales even when you don&#8217;t make a deliberate effort for that.</p><h3 id="reasonn.2theyprovideanewkindofglue">Reason N. 2 They provide a new kind of glue</h3><p>&#8220;<em>Such a catalogue of “advantages” is all very well, but one must not be surprised if outsiders don&#8217;t take it too seriously. It says a lot about what functional programming isn&#8217;t (it has no assignment, no side effects, no flow of control) but not much about what it is. The functional programmer sounds rather like a mediæval monk, denying himself the pleasures of life in the hope that it will make him virtuous.</em>&#8221; &#8211; John Hughes</p><p>So far it seems that if we strip other languages from features such as mutability and control flow, then we would have the same benefits of functional programming, without the hassle of learning a new language. Hence, the question remains: <em>why should we care to learn FP in the first place?</em></p><p>Flashback circa 1968. We are near Garmisch Germany, and NATO is holding <em>the</em> seminal conference on &#8220;Software Engineering&#8221;. So far everyone seems to agree on one particular conclusion: software is in <em>crisis</em>. Projects are running over-budget, over-time, and with low quality. They are inefficient, they don&#8217;t meet the requirements, their code is difficult to maintain. Some software isn&#8217;t even delivered&#8230; ever! They realized all this <em>before</em> Windows™ was presented to the world. <a
href="#fn:19" id="fnref:19" title="see footnote" class="footnote">[19]</a> Forty years later, what have we learned? <a
href="#fn:20" id="fnref:20" title="see footnote" class="footnote">[20]</a></p><p>From the several ideas there discussed, one of them looked at computer software as they looked at complex electronic systems: software should be <em>componentized</em>, i.e., built from prefabricated components <a
href="#fn:21" id="fnref:21" title="see footnote" class="footnote">[21]</a>. Powerful idea! In the subsequent years, we saw the appearance of Unix&#8217;s Pipes and Filters, Objective-C, OLE, COM and the concept of <em>Frameworks</em> in general.</p><p>On the object-oriented side, a similar race gave us the <em>AbstractSingletonProxyFactoryBean</em>&#8230; whatever that is. <a
href="#fn:22" id="fnref:22" title="see footnote" class="footnote">[22]</a></p><p>The crux of modularization is a two-step process: (1) you first divide your problem into sub-problems, and then (2) you combine (glue) the results. You can look at this like an electronic circuit; you separate your problem (a computer) into sub-problems (CPU, Memory, GPU&#8230;) and then you provide the glue (copper circuits and wires that roughly match inputs with outputs).</p><p>What happens when you provide the wrong kind of glue, say, plastic instead of copper, or wire an input to another input? Best-case scenario: it doesn&#8217;t work. <a
href="#fn:23" id="fnref:23" title="see footnote" class="footnote">[23]</a></p><p>Another (different) way to view modularization is like a big puzzle. Pieces have a <em>shape</em> and they only <em>compose</em> if their shape match. If done correctly, you are kept safe from combining components that don&#8217;t talk to each other, simply because their shape doesn&#8217;t allow it. This is akin to the experience given by (strongly-typed) functional languages. <a
href="#fn:24" id="fnref:24" title="see footnote" class="footnote">[24]</a> Instead of declaring capabilities of objects, you define <em>transformations</em> that accept <em>things</em> of a particular shape. For example, to filter out elements of a container structure, you don&#8217;t really need a function for every kind of containers out there (Lists, Trees&#8230;) As long as the structure you&#8217;re providing has the <em>shape</em> of something that can be iterated over, then you simple iterate ruling out objects that don&#8217;t match your filter. <a
href="#fn:25" id="fnref:25" title="see footnote" class="footnote">[25]</a></p><p>Functional programming provides new kinds of glue, such as <em>higher-order functions</em>, <em>function composition</em>, <em>point-free definitions</em>, <em>type-classes</em> and <em>higher-kinded types</em>. Some languages can even check these &#8220;glues&#8221; at compile time, making your program safer. You write less code, you reuse more, and it keeps you from reinventing the <em>square wheel</em>.</p><p>Again, consider the number of components an ad-tech platform now comprehends, yield managers, ad decision logic, RTB clients, forecast engines, logging, campaign optimizers, and you&#8217;ll understand why improving modularization (and making sure they fit with each other) is a crucial step in the industry.</p><h3 id="reasonn.1becauseitscool">Reason N. 1 Because it&#8217;s cool</h3><p><em>&#8220;C is quirky, flawed, and an enormous success.&#8221;</em> &#8211; Dennis M. Ritchie.</p><p>Much of the above was known more than twenty years ago, at a time where C was the <em>de-facto</em> king of programming languages. And yet, here we are, claiming again and again the advantages of functional programming. What really changed? Is imperative programming just getting old? Is Functional Programming becoming a hype?</p><p>The fact that C was a huge success is (arguably) a mystery <a
href="#fn:26" id="fnref:26" title="see footnote" class="footnote">[26]</a>. C is (was) well-known, widely adopted by both the industry and the academia, and hence enjoyed an incredible amount of scrutiny. A huge amount of C libraries and frameworks became promptly available in the wild. Yes, everyone knew C wasn&#8217;t perfect. In fact, C&#8217;s unsafe type system was an imminent disaster. Turing award laureate Tony Hoare once called the &#8220;null reference&#8221; <a
href="#fn:27" id="fnref:27" title="see footnote" class="footnote">[27]</a> its billion-dollar mistake. And yet, even today, C ranks second in the Tiobe popularity index. Why?</p><p>Perhaps the keyword here is <em>establishment</em>. All those frameworks and libraries and tools built for C (in C) made it the number one choice. People didn&#8217;t even think for a second. If C is popular, and has <em>everything</em> I need, why choose another language?</p><p>Of course, the fallacy lies in the definition of &#8220;need&#8221;&#8230; Notwithstanding, there&#8217;s a bitter lesson here, learned the hard way by Haskell proponents: if you fail to provide the <em>complete experience</em>, it really doesn&#8217;t matter how good your product is.</p><p>So what changed?</p><p>We&#8217;ve now come full circle to the title of this article. Maybe some of you have been wondering about the usage of the prefix (post-) in post-functional. What is different today from what we had 20 years ago, is that the functional paradigm is no longer relegated to obscure, academic corners, whimsically forcing you out of your comfort zone.</p><p>Instead, what we are now observing is a merge between object-oriented and functional languages, at different degrees of realization. At the lowest level, we see the latest version of the C++ standard (0&#215;11), incorporate the notion of lambdas and function objects. The same is true for Java 8, and was true for C# 2.0 and all its subsequent versions. And it&#8217;s not just higher-order functions. In Biancuzzi&#8217;s book &#8220;Masterminds of Programming&#8221;, we can read Anders Hejlsberg (lead C# developer) rant on how the future of the language lies in adopting FP techniques to cope with multi-core/parallel programming. We may even go as far as Microsoft&#8217;s release of F# as a first-class language for the &#8220;big-data&#8221; industry <a
href="#fn:28" id="fnref:28" title="see footnote" class="footnote">[28]</a>, that runs on top of the CLR.</p><p>And finally we have Scala. A language created by Prof. Martin Odersky, that fuses object-orientation and functional programming at their most fundamental level. Its secret? It runs on top of the Java Virtual Machine (JVM), and seamlessly interoperates with existing Java libraries and frameworks. It was specifically designed for scaling at large, and has enjoyed several successful adoption stories in the industry, including Twitter, LinkedIn, Foursquare, and The Guardian, just to name a few. &#8220;<em>Functional Programming Principles in Scala</em>&#8221; <a
href="#fn:29" id="fnref:29" title="see footnote" class="footnote">[29]</a>, an MOOC held by Coursera, had more that 50.000 students registered, becoming one of the most successful on-line courses. It&#8217;s not hard to conclude that, if <em>these</em> players are using Scala, maybe one should keep an eye on it.</p><p>So, post-functionalism is about realizing that the <em>ecosystem</em> matters. Instead of trying to get people out of its comfort zone, it brings those features into what people are comfortable with <a
href="#fn:30" id="fnref:30" title="see footnote" class="footnote">[30]</a>. Post-functionalism is about realizing that <em>both</em> object-oriented and functional programming can contribute to a new (merged) <em>thing</em>: OO is an excellent tool to design &#8220;components&#8221;, the outward limits of systems, while FP provides an invaluable tool to express its inwards. This thing is <em>object-functional</em> programming.</p><p>(Post-)Functionalism is now a reality. To some extent, it doesn&#8217;t really matter if you&#8217;ve been evangelized by this article. I&#8217;ve claimed that (post-)functional programming will give you better, more robust, more scalable, more modular programs. It would make you better cope with the specific needs of the fast growing industry that is the <em>ad-tech</em>, because the issues <em>ad-tech</em> has (high-availability, high-scalability, robustness, fault-tolerance, adaptiveness) <em>are</em> the issues that FP learned to solve decades ago. But, perhaps, the most pragmatic reason why post-functional programming <em>matters</em> is because you will no longer be able to ignore it.</p><div
class="footnotes"><hr
/><ol><li
id="fn:1"><p>Where Knuth lift the status of <em>Art</em> to the mere act of reading his work. <a
href="#fnref:1" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:2"><p>People seem to mistake rigorous with rigid. The former implies rules, while the later implies resistance to change. <a
href="#fnref:2" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:3"><p>Before most readers run away upon gazing the words &#8220;formal&#8221;, please consider than I am a professor of Agile Methodologies, so bear with me for a while <img
src='http://www.shiftforward.eu/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> <a
href="#fnref:3" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:4"><p>I would argue we &#8220;shouldn&#8217;t&#8221;, unless we are hardcore researchers is those topics. <a
href="#fnref:4" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:5"><p>And yet before another exodus <em>en masse</em>, do please consider that Java and C# are also part of my courses&#8217; syllabus. <a
href="#fnref:5" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:6"><p>Obeying rigorously doesn&#8217;t make the act rigorous. <a
href="#fnref:6" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:7"><p>These reasons are no longer true; today&#8217;s compilers are much more efficient at producing assembly code than an human is, due to the magic of out-of-order execution, caches, pipelines, multi-cores and SIMD instructions. <a
href="#fnref:7" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:8"><p>See <a
href="http://nescala.org/2013/talks#47">this</a>. <a
href="#fnref:8" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:9"><p>There are countless many other reasons, not necessarily exclusive of FP, some of which are highly technical and out of scope of this article. For the curious, read about <em>unified type systems</em>, <em>type inference</em>, <em>anonymous functions</em>, <em>closures</em>, <em>immutability</em>, <em>lazy evaluation</em>, <em>delimited continuations</em>, <em>higher-order functions</em>, <em>higher-kinded types</em>, <em>nested functions</em>, <em>currying</em>, <em>pattern matching</em>, <em>algebraic data types</em>, <em>tail recursion</em>, <em>partial functions</em>, <em>structural types</em>, <em>dependent types</em>, <em>explicitly typed self references</em>, <em>type bounds</em>, <em>variance</em>, <em>type annotations</em>, <em>type views</em>, <em>type classes</em>, and follow the white rabbit&#8230; <a
href="#fnref:9" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:10"><p>A mathematician and civil architect. <a
href="#fnref:10" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:11"><p>Lacking something of value doesn&#8217;t make a thing worthless. <a
href="#fnref:11" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:12"><p>If we also consider the inverse of addition (subtraction), then we have a <em>group</em>. <a
href="#fnref:12" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:13"><p>Mathematicians may even argue that <em>these</em> are the true type of patterns. <a
href="#fnref:13" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:14"><p>Another cool property (this one given by <em>groups</em>) is that there are some operations that cancel each other; if you sum and then subtract the same number, you come back to where you&#8217;ve started. In a more general sense, if your functions form a group, then you&#8217;ve just gained some optimisation techniques <em>for free</em>. <a
href="#fnref:14" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:15"><p>Mapreduce is actually a very good lesson on how people are easily attached to labels. A few years ago, even before &#8220;big data&#8221; became the buzzword it is today, everyone in the ad space thinking on &#8220;big&#8221; data was talking about mapreduce. However, and despite its fundamental principles being mostly those of functional programming, many developers that loved mapreduce simultaneously loathed anything related to FP. Today&#8217;s hype in big-data is <em>Hadoop</em>. Go figures&#8230; <a
href="#fnref:15" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:16"><p>There&#8217;s something very dysfunctional in the way dynamic OO programming deals with mutability. On one hand, the whole idea behind OO is that (inner) details don&#8217;t matter. A car is a car, and it has the functionality expected from a car. You &#8220;ask&#8221; the car to start, accelerate, break and stop. It&#8217;s a powerful concept particularly when coupled with abstraction; every vehicle should adhere to this <em>interface</em> of accelerating and breaking. What really spoils everything is that you never know when a Car will start behaving differently the second time you look at it. Now, what you can argue &#8211; and I concur &#8211; is that there&#8217;s something here associated with <em>scale</em>: big things (like cars or databases) are expected to change internally. But a <em>clog</em> is not. And when clogs suddenly transform into valves&#8230; <a
href="#fnref:16" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:17"><p>Some people, when confronted with a problem, think: hey, I can solve this with reflection. Now they have two problems. As with every tool, meta-programming is not a free lunch. <a
href="#fnref:17" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:18"><p>Purity, as with so many other qualities, comes in sizes. <a
href="#fnref:18" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:19"><p>Perhaps not a fair joke, but I couldn&#8217;t resist <img
src='http://www.shiftforward.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> <a
href="#fnref:19" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:20"><p>Actually, we learned a lot; we now know that requirements are expected to change, and that gave us <em>Agile Methodologies</em>. We know that Moore&#8217;s Law is coming to an end, and that gave us <em>Parallel Programming</em>. Quality is important, and that gave us <em>Test-Driven Development</em>. We also know that a suitable algorithm is orders of magnitude better than &#8220;premature optimization&#8221;&#8230; But, we <em>kinda keep forgetin&#8217;</em> about all that. <a
href="#fnref:20" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:21"><p>Doug McIlroy, <em>&#8220;Mass Produced Software Components&#8221;</em> in Proceedings of Software Engineering Concepts and Techniques, 1969. <a
href="#fnref:21" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:22"><p>&#8220;<em>A convenient proxy factory bean superclass for proxy factory beans that create only singletons.</em>&#8221; (see <a
href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/framework/AbstractSingletonProxyFactoryBean.html">here</a> and <a
href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/beans/factory/BeanClassLoaderAware.html">here</a>). <a
href="#fnref:22" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:23"><p>Worst-case scenario, it explodes in your face. <a
href="#fnref:23" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:24"><p>In nature, proteins also act in a similar fashion: they bind to other molecules due to their &#8220;shape&#8221;. <a
href="#fnref:24" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:25"><p>This simple notion of filtering a collection is a nuisance in most imperative programming languages. Not only most of them can&#8217;t even return the same collection type (e.g., in C# you start with a <em>List</em> and end with an <em>IEnumerable</em>), but the filter implementation is repeated <em>for every kind of container</em>. <a
href="#fnref:25" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:26"><p>A kind of mystery like the <a
href="http://en.wikipedia.org/wiki/Videotape_format_war">video-tape war</a>. <a
href="#fnref:26" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:27"><p>In fact, he was talking about Algol, to which C owes its roots. <a
href="#fnref:27" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:28"><p>I&#8217;m deliberately incurring into an &#8220;appeal to authority&#8221; fallacy. <a
href="#fnref:28" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:29"><p>See <a
href="https://www.coursera.org/course/progfun">this</a>. <a
href="#fnref:29" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li><li
id="fn:30"><p>To be completely honest, functional-programming also comes riddled with mathematical jargon and category-theory concepts that may make your head explode. Your mileage may vary&#8230; <a
href="#fnref:30" title="return to article" class="reversefootnote">&#160;&#8617;</a></p></li></ol></div><p>The post <a
href="http://www.shiftforward.eu/techtalks/2013/03/why-post-functional-programming-matters/">Why (Post-)Functional Programming Matters</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></content:encoded> <wfw:commentRss>http://www.shiftforward.eu/techtalks/2013/03/why-post-functional-programming-matters/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Scala path-dependent types &#8211; A real world example</title><link>http://www.shiftforward.eu/techtalks/2013/02/scala-path-dependent-types-a-real-world-example/</link> <comments>http://www.shiftforward.eu/techtalks/2013/02/scala-path-dependent-types-a-real-world-example/#comments</comments> <pubDate>Mon, 11 Feb 2013 18:24:53 +0000</pubDate> <dc:creator>ShiftForward</dc:creator> <category><![CDATA[Tech Talks]]></category> <category><![CDATA[java]]></category> <category><![CDATA[path-dependent types]]></category> <category><![CDATA[scala]]></category> <guid
isPermaLink="false">http://www.shiftforward.eu/?p=730</guid> <description><![CDATA[<p>In this post, ShiftForward&#8217;s Rui Gonçalves presents a Scala feature that has recently helped us through a design choice in our AdForecaster system: more concretely, a feature of its type system. A type system is, indeed, a very powerful tool for a programming language. In fact, it is a concrete case of a formal method; it [...]</p><p>The post <a
href="http://www.shiftforward.eu/techtalks/2013/02/scala-path-dependent-types-a-real-world-example/">Scala path-dependent types &#8211; A real world example</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></description> <content:encoded><![CDATA[<p>In this post, ShiftForward&#8217;s <a
title="Who" href="http://www.shiftforward.eu/who-is-shiftforward/">Rui Gonçalves</a> presents a Scala feature that has recently helped us through a design choice in our AdForecaster system: more concretely, a feature of its type system.</p><p>A type system is, indeed, a very powerful tool for a programming language. In fact, it is a concrete case of a formal method; it provides us a near mathematical proof that programs that compile successfully obey a set of rules and restrictions and, as such, are bug-free in that respect. For example, after compiling a Java program, we know for sure that the it will not do a division of a number with a string and that, if our method foo receives an integer as argument, it will not be called anywhere with an argument of any type other than an integer.</p><p>This blog post focuses on how a programming language can be used to model more advanced code restrictions and check them at compile time. By checking them at compile time, such languages enable the detection of bugs which otherwise would only be caught at runtime, when systems are already deployed (or by manually writing tests – though tests can be wrongly written and may not cover all potential failure cases). We assume basic knowledge of Java programming, even though we feel it may not be necessary to delve into the code to understand the main problem and concepts presented.</p><p>Consider the following scenario:</p><ul><li>Our forecast system, at a particular stage, simulates the ad server decision mechanism in order to predict the number of hits for each campaign;</li><li>The delivery algorithm is modelled as a component with <b>two</b> operations:<ul><li><b>Pre-process.</b> It must be able to pre-process a list of campaigns, yielding a structure that allows faster evaluation of delivery rules. For example, it can sort the campaigns according to their priority or index campaigns according to a targeting rule;</li><li><b>Execute.</b> It must be able to quickly determine which campaign will be delivered for a given request, using the aforementioned structure. This decision step is done a huge number of times – once per simulated request;</li></ul></li><li><b>Different algorithms</b> can yield completely<b> different structures</b> in the pre-processing phase;</li><li>The algorithm must be <b>stateless</b>, as a single instance is shared by many concurrent threads and is used to execute many forecasts.</li></ul><p>We want our system to be <b>decoupled from the delivery algorithm</b> it is using, in order for us to switch the delivery algorithm according to our clients’ needs and to easily introduce new features, such as pacing and tandem. Moreover, the specific algorithm to use <b>may not yet be known at compile time</b>, e.g. its name can be indicated as a string via API.</p><p>Let’s think how we could do this using Java. The most natural encoding we could do would be to make our Algorithm a generic class, like this:</p><pre>public interface Algorithm&lt;CampaignContainer&gt; {
    CampaignContainer preprocess(List&lt;Campaign&gt; campaigns);
    Campaign run(CampaignContainer campaigns, Request req); // returns null if no booking was made
}</pre><p>&nbsp;</p><p>Following this approach, our main Forecast class would look like this:</p><pre>public class Forecast {
    &lt;CampaignContainer&gt; void forecast(List&lt;Campaign&gt; campaigns, List&lt;Request&gt; requests, Algorithm&lt;CampaignContainer&gt; algorithm) {
        CampaignContainer preprocessedCampaigns = algorithm.preprocess(campaigns);
        List&lt;Campaign&gt; results = new ArrayList&lt;&gt;();
        for(Request req: requests) {
            results.add(algorithm.run(preprocessedCampaigns, req));
        }
        // (...)
    }
}</pre><p>&nbsp;</p><p>Note that the forecast method was also made generic, in order to accept heterogeneous Algorithm classes.</p><p>As we said before, the specific algorithm to use is not known at compile time. To instantiate an algorithm given a class name &#8211; using a mechanism known as reflection – we can do:</p><pre>&lt;CampaignContainer&gt; Algorithm&lt;CampaignContainer&gt; getAlgorithm(String className) throws Exception {</pre><pre>    return (Algorithm&lt; CampaignContainer&gt;) Class.forName(className).newInstance();
}</pre><p>&nbsp;</p><p>This method will cause a compiler warning, indicating that an unsafe cast is being done. That happens because the compiler erases generic types; e.g., a program can’t distinguish between an Algorithm&lt;String&gt; and an Algorithm&lt;Integer&gt;.</p><p>However, there is a bigger problem: we don’t know which specific type is CampaignContainer when we call forecast! When we call the getAlgorithm method, we should know in advance what is the type of CampaignContainer and, as it can be anything, this solution is not suitable to support arbitrary structures as an output of the pre-processing step.</p><p>In Java, the only way we could do this is to forget about types and generics at all and make our algorithms return and receive objects of type Object (which is a superclass of every other class) instead of CampaignContainer:</p><pre>interface Algorithm {</pre><pre>    Object preprocess(List&lt;Campaign&gt; campaigns);</pre><pre>    Campaign run(Object campaigns, Request req); // returns null if no booking was made
}</pre><p>&nbsp;</p><p>This is obviously a bad and unsafe design choice, as the run method is now able to take <span
style="text-decoration: underline;">any</span> object as parameter and will yield runtime errors if some method calls it in the wrong way. This also implies that, inside run, algorithms must always cast the campaigns argument to its concrete type, which is a seemingly unnecessary operation and probably expensive overall, considering that run will be called a huge number of times. (Relinquishing type-safety)</p><p>When comparing programming languages, we should evaluate for ourselves the flexibility they give us to correct and easily encode our control flows and restrictions. Let’s think for a minute here: must the Forecast class really have to know what is the campaign container? Given a specific instance of Algorithm (without any more information), the only thing we want to enforce is that <b>the first input of the </b><b>run</b><b> method is of the same type as the return value of a </b><b>preprocess</b><b> call</b>. Besides that, it doesn’t really matter what is the particular type of the container.</p><p>In Scala, this problem can be properly encoded using a feature called <span
style="text-decoration: underline;">path-dependent types</span>. Let’s see how the equivalent code in that language looks like:</p><pre>trait Algorithm {</pre><pre>    type CampaignContainer // an abstract type field; it must be defined by subclasses</pre><pre>    def preprocess(campaigns: Seq[Campaign]): CampaignContainer</pre><pre>    def run(campaigns: CampaignContainer, req: Request): Campaign</pre><pre>}</pre><pre>class Forecast {</pre><pre>    def forecast(campaigns: Seq[Campaign], requests: Seq[Request], algorithm: Algorithm) {</pre><pre>        val preprocessedCampaigns: <b>algorithm.CampaignContainer</b> = algorithm.preprocess(campaigns)</pre><pre>        val results = requests.map { req =&gt; algorithm.run(preprocessedCampaigns, req) }</pre><pre>        // (...)</pre><pre>    }</pre><pre>}</pre><p>&nbsp;</p><p>Scala has the concept of <span
style="text-decoration: underline;">abstract types</span>: types that, just like abstract methods, must be defined by subclasses. Our CampaignContainer here is declared as an abstract type in the Algorithm class, and it is the concrete subclass of the latter that defines what a CampaignContainer is. Therefore, the abstract type CampaignContainer is <span
style="text-decoration: underline;">dependent of the instance it refers to</span>.</p><p>Let’s quickly see a concrete algorithm that returns a Map mapping string keys to campaigns in the pre-processing step:</p><pre>class SimpleAlgorithm extends Algorithm {</pre><pre>    type CampaignContainer = Map[String, Campaign]</pre><pre>    def preprocess(campaigns: Seq[Campaign]): Map[String, Campaign] = (...) // code for creating the Map here</pre><pre>    def run(campaigns: Map[String, Campaign], req: Request): Option[Campaign] = (...) // code for choosing the campaign here</pre><pre>}</pre><p>&nbsp;</p><p>The best part is that our Forecast class – a class from the outside of this type hierarchy – can refer to this abstract type and use it in their variables. In the forecast method, our preprocessedCampaigns is an instance of algorithm.CampaignContainer; it is called a <b>path-dependent type</b>. This models the exact relation we wanted for our entities: independently of the concrete type of our Algorithm, we assure that the run method (that, in forecast, takes an algorithm.CampaignContainer as argument) can only take structures returned by a call to preprocess on the algorithm instance. It is important to note that all of these restrictions are <b>enforced at compile time</b> and, as such, <b>do not affect the runtime performance</b> of our system.</p><p>More advanced type systems, such as the one featured in Scala, increase our confidence in the systems we develop and help us <b>reduce</b> the number of <b>bugs before deployment</b> – which ultimately benefits, without a doubt, our clients. It is important to note that these important validations doesn’t require extra effort from developers – no need to manually write tests or to run third-party tools – and have no runtime performance impact, which is always a key concern when developing online advertisement systems.</p><p>The complete source code of this example can be seen here: <a
title="AlgorithmJava.java" href="http://www.shiftforward.eu/wp-content/uploads/AlgorithmJava.java" target="_blank">AlgorithmJava</a> and <a
title="AlgorithmScala.scala" href="http://www.shiftforward.eu/wp-content/uploads/AlgorithmScala.scala" target="_blank">AlgorithmScala</a>. If you are curious and have some knowledge in Java, I recommend you to compare the syntax of both languages and to read further about Scala <a
title="The Scala Programming Language" href="http://www.scala-lang.org/node/25" target="_blank">here</a>.</p><p>The post <a
href="http://www.shiftforward.eu/techtalks/2013/02/scala-path-dependent-types-a-real-world-example/">Scala path-dependent types &#8211; A real world example</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></content:encoded> <wfw:commentRss>http://www.shiftforward.eu/techtalks/2013/02/scala-path-dependent-types-a-real-world-example/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Binomial Queues</title><link>http://www.shiftforward.eu/techtalks/2013/01/binomial-queues/</link> <comments>http://www.shiftforward.eu/techtalks/2013/01/binomial-queues/#comments</comments> <pubDate>Mon, 14 Jan 2013 18:56:34 +0000</pubDate> <dc:creator>ShiftForward</dc:creator> <category><![CDATA[Tech Talks]]></category> <guid
isPermaLink="false">http://www.shiftforward.eu/?p=715</guid> <description><![CDATA[<p></p><p>The post <a
href="http://www.shiftforward.eu/techtalks/2013/01/binomial-queues/">Binomial Queues</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></description> <content:encoded><![CDATA[<p><iframe
src="http://prezi.com/embed/f78h9tvmgouw/?bgcolor=ffffff&amp;lock_to_path=0&amp;autoplay=no&amp;autohide_ctrls=0" width="850" height="825" frameBorder="0"></iframe></p><p>The post <a
href="http://www.shiftforward.eu/techtalks/2013/01/binomial-queues/">Binomial Queues</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></content:encoded> <wfw:commentRss>http://www.shiftforward.eu/techtalks/2013/01/binomial-queues/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Monoids</title><link>http://www.shiftforward.eu/techtalks/2013/01/monoids/</link> <comments>http://www.shiftforward.eu/techtalks/2013/01/monoids/#comments</comments> <pubDate>Mon, 14 Jan 2013 18:48:34 +0000</pubDate> <dc:creator>ShiftForward</dc:creator> <category><![CDATA[Tech Talks]]></category> <guid
isPermaLink="false">http://www.shiftforward.eu/?p=710</guid> <description><![CDATA[<p></p><p>The post <a
href="http://www.shiftforward.eu/techtalks/2013/01/monoids/">Monoids</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></description> <content:encoded><![CDATA[<p><iframe
src="/lib/revealjs/monoids.html" border="0" width="850px" height="825px"></iframe></p><p>The post <a
href="http://www.shiftforward.eu/techtalks/2013/01/monoids/">Monoids</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></content:encoded> <wfw:commentRss>http://www.shiftforward.eu/techtalks/2013/01/monoids/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Finger trees for the impatient</title><link>http://www.shiftforward.eu/techtalks/2013/01/finger-trees-for-the-impatient/</link> <comments>http://www.shiftforward.eu/techtalks/2013/01/finger-trees-for-the-impatient/#comments</comments> <pubDate>Mon, 14 Jan 2013 18:45:40 +0000</pubDate> <dc:creator>ShiftForward</dc:creator> <category><![CDATA[Tech Talks]]></category> <guid
isPermaLink="false">http://www.shiftforward.eu/?p=691</guid> <description><![CDATA[<p></p><p>The post <a
href="http://www.shiftforward.eu/techtalks/2013/01/finger-trees-for-the-impatient/">Finger trees for the impatient</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></description> <content:encoded><![CDATA[<p><iframe
src="/lib/revealjs/fingertreesfortheimpatient.html" border="0" width="850px" height="825px"></iframe></p><p>The post <a
href="http://www.shiftforward.eu/techtalks/2013/01/finger-trees-for-the-impatient/">Finger trees for the impatient</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></content:encoded> <wfw:commentRss>http://www.shiftforward.eu/techtalks/2013/01/finger-trees-for-the-impatient/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>ShiftForward Recruta Novos Colaboradores</title><link>http://www.shiftforward.eu/shiftforward/2012/03/shiftforward-recruta-novos-colaboradores/</link> <comments>http://www.shiftforward.eu/shiftforward/2012/03/shiftforward-recruta-novos-colaboradores/#comments</comments> <pubDate>Fri, 02 Mar 2012 16:57:30 +0000</pubDate> <dc:creator>Hugo Ferreira</dc:creator> <category><![CDATA[shiftforward]]></category> <guid
isPermaLink="false">http://www.shiftforward.eu/?p=167</guid> <description><![CDATA[<p>A ShiftForward é uma start-up jovem, dinâmica e empreendedora de I&#038;D que procura soluções inovadoras de arquitectura e engenharia de software tanto para os seus clientes como para os seus próprios produtos. Conta com uma cultura de trabalho que valoriza resultados, aprendizagem e inovação; uma política de recrutamento que insiste em contratar o melhor talento [...]</p><p>The post <a
href="http://www.shiftforward.eu/shiftforward/2012/03/shiftforward-recruta-novos-colaboradores/">ShiftForward Recruta Novos Colaboradores</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></description> <content:encoded><![CDATA[<p>A ShiftForward é uma start-up jovem, dinâmica e empreendedora de I&#038;D que procura soluções inovadoras de arquitectura e engenharia de software tanto para os seus clientes como para os seus próprios produtos. Conta com uma cultura de trabalho que valoriza resultados, aprendizagem e inovação; uma política de recrutamento que insiste em contratar o melhor talento disponivel no mercado e uma carteira de clientes internacionais que insiste em não parar de crescer.</p><p>Localizada no Parque de Ciência de Tecnologia da Universidade do Porto (UPTEC), a ShiftForward procura agora recém licenciados (até 3 anos de experiência) com formação em Engenharia Informática (FEUP, UM, ISEP ou equivalentes), com as seguintes características:</p><p>1. Conhecimento prévio em Microsoft .NET (C#) e frameworks associadas;<br
/> 2. Conhecimento prévio de tecnologias e infra-estruturas Web;<br
/> 3. Motivado para aprender novas tecnologias, novas linguagens de programação e formas avançadas de desenvolvimento;<br
/> 4. <em>Team-worker</em> e <em>problem-solver;</em><br
/> 5. Nível de Inglês <a
href="http://europass.cedefop.europa.eu/en/resources/european-language-levels-cefr" title="Europass: European language levels" target="_blank">Europass</a> B2 ou superior.</p><p>Oferece:</p><p>1. Contrato de trabalho inicial por 6 meses, com possibilidade de renovação e integração na empresa;<br
/> 2. Integração numa equipa internacionalizada;<br
/> 3. Ambiente de desenvolvimento ágil (scrum + xp);<br
/> 4. Remuneração compatível com o nível de conhecimentos, acima dos valores de mercado;<br
/> 5. Horário de trabalho flexível.</p><p>Para tal, os interessados devem enviar um email com o CV para info@shiftforward.eu. No caso de não terem experiência profissional prévia, agradecemos que seja anexado um resumo com as classificações de cada disciplina do curso.</p><p>The post <a
href="http://www.shiftforward.eu/shiftforward/2012/03/shiftforward-recruta-novos-colaboradores/">ShiftForward Recruta Novos Colaboradores</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></content:encoded> <wfw:commentRss>http://www.shiftforward.eu/shiftforward/2012/03/shiftforward-recruta-novos-colaboradores/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Paulo Cunha Discusses The ShiftForward Tech Development Solution, Its Value To Local European Ad Tech Players And Where It Sits In The Eco-System</title><link>http://www.shiftforward.eu/shiftforward/2011/10/paulo-cunha-discusses-the-shiftforward-tech-development-solution-its-value-to-local-european-ad-tech-players-and-where-it-sits-in-the-eco-system/</link> <comments>http://www.shiftforward.eu/shiftforward/2011/10/paulo-cunha-discusses-the-shiftforward-tech-development-solution-its-value-to-local-european-ad-tech-players-and-where-it-sits-in-the-eco-system/#comments</comments> <pubDate>Wed, 26 Oct 2011 11:39:42 +0000</pubDate> <dc:creator>ShiftForward</dc:creator> <category><![CDATA[shiftforward]]></category> <category><![CDATA[exchangewire]]></category> <category><![CDATA[press]]></category> <guid
isPermaLink="false">http://www.shiftforward.eu/?p=120</guid> <description><![CDATA[<p>In interview with ExchangeWire Paulo Cunha talks about ShiftForward and it&#8217;s value proposition. Can you give an overview of the ShiftForward proposition in Europe? ShiftForward’s core is its know-how in technology development and its application in the online advertising industry. Online advertising has very specific technical and business requirements, often not found in other fields, [...]</p><p>The post <a
href="http://www.shiftforward.eu/shiftforward/2011/10/paulo-cunha-discusses-the-shiftforward-tech-development-solution-its-value-to-local-european-ad-tech-players-and-where-it-sits-in-the-eco-system/">Paulo Cunha Discusses The ShiftForward Tech Development Solution, Its Value To Local European Ad Tech Players And Where It Sits In The Eco-System</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></description> <content:encoded><![CDATA[<p>In interview with ExchangeWire Paulo Cunha talks about ShiftForward and it&#8217;s value proposition.</p><p><strong>Can you give an overview of the ShiftForward proposition in Europe?<br
/> </strong></p><p>ShiftForward’s core is its know-how in technology development and its application in the online advertising industry. Online advertising has very specific technical and business requirements, often not found in other fields, that can take engineering teams a long time to be up to speed with what the business and market are talking about.</p><p>We provide this expert independent advice to companies seeking to adopt or create their own technology for various purposes, from Ad Serving to Behavioural Targeting or Data Management Platforms. This means researching and designing solutions, defining the software architecture to support it and guiding the company’s engineering teams during the development cycle.</p><p><a
href="http://www.exchangewire.com/blog/2011/10/24/paulo-cunha-discusses-the-shiftforward-tech-development-solution-its-value-to-local-european-ad-tech-players-and-where-it-sits-in-the-eco-system/">Continue reading the full article on ExchangeWire</a></p><p>The post <a
href="http://www.shiftforward.eu/shiftforward/2011/10/paulo-cunha-discusses-the-shiftforward-tech-development-solution-its-value-to-local-european-ad-tech-players-and-where-it-sits-in-the-eco-system/">Paulo Cunha Discusses The ShiftForward Tech Development Solution, Its Value To Local European Ad Tech Players And Where It Sits In The Eco-System</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></content:encoded> <wfw:commentRss>http://www.shiftforward.eu/shiftforward/2011/10/paulo-cunha-discusses-the-shiftforward-tech-development-solution-its-value-to-local-european-ad-tech-players-and-where-it-sits-in-the-eco-system/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>ShiftForward ^&gt;&gt; 1.0</title><link>http://www.shiftforward.eu/shiftforward/2011/05/shiftforward-1-0/</link> <comments>http://www.shiftforward.eu/shiftforward/2011/05/shiftforward-1-0/#comments</comments> <pubDate>Wed, 11 May 2011 16:34:40 +0000</pubDate> <dc:creator>ShiftForward</dc:creator> <category><![CDATA[shiftforward]]></category> <category><![CDATA[startups]]></category> <guid
isPermaLink="false">http://shiftforward.eu/?p=11</guid> <description><![CDATA[<p>ShiftForward founded, over an al-fresco beer on a summer night</p><p>The post <a
href="http://www.shiftforward.eu/shiftforward/2011/05/shiftforward-1-0/">ShiftForward ^>> 1.0</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></description> <content:encoded><![CDATA[<p>ShiftForward founded, over an al-fresco beer on a summer night</p><p>The post <a
href="http://www.shiftforward.eu/shiftforward/2011/05/shiftforward-1-0/">ShiftForward ^>> 1.0</a> appeared first on <a
href="http://www.shiftforward.eu">ShiftForward - online advertising technology r&amp;d for DSPs, SSPs, DMPs, Ad Exchanges, Ad Networks, Agencies and Publishers</a>.</p>]]></content:encoded> <wfw:commentRss>http://www.shiftforward.eu/shiftforward/2011/05/shiftforward-1-0/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- Dynamic page generated in 0.443 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2013-05-20 21:36:45 -->
