tag:blogger.com,1999:blog-30886097137680607082024-03-02T10:28:43.101-07:00agiledeveloper| <a href="http://www.agiledeveloper.com">View the main site</a> | <a href="http://www.agilelearner.com">Visit agilelearner.com</a> | <a href="https://twitter.com/intent/follow?screen_name=venkat_s">Follow @venkat_s on Twitter</a>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.comBlogger344125tag:blogger.com,1999:blog-3088609713768060708.post-43879621019996057412022-02-07T06:24:00.004-07:002022-02-07T09:05:17.212-07:00 Build a professional relationship then eventually ask for a reference<p>A relative of a friend emailed me asking if I can provide a professional reference. I have known this person for some time, in a social setting, occasionally meeting at events. He's a good human, but I know little about his work, professional capabilities, ability to show up on time, how this person deals with challenges, and so many more things. I politely declined saying that I am not the right person to provide a professional reference since we do not have a working relationship.</p><p>It turns out many people think that they can get a reference if they have interacted with someone in some capacity. But, it takes a lot more.</p><p>Over the years I have provided a number of references for students and colleagues that I have worked with.</p><p>For instance, in one of the projects that I was a consultant on, the team leader reached out to me about three years later and asked if I can provide a reference. I immediately agreed and wrote a very favorable one for her. The reason, we worked together, we interacted on a daily basis. I was able to see how swiftly and wisely she made decisions when I worked with her on the project. I had nice things to say because we had the opportunity to learn from and about each other.</p><p>It is not unusual for me to spend 30 minutes to an hour talking to a potential employer about the strengths and weaknesses of a student who was in my class and why the company should hire this person. However, in this case, I have substantial things to say about the student, what we interacted about, what kind of technical questions did the student raise, what kind of solutions they brought about that intrigued me, did the student show interest in learning far beyond "hey I have a question about the assignment." Did the student participate, did the student refer to articles, blog posts, did the student schedule time to chat, to geek out, to discuss about their views on software development, profession, professionalism, the industry, just about anything to demonstrate a keen interest in the field? In short, did we interact one-on-one on multiple occasions, discussing technical and professional topics. Did I get to take a peek at your thinking?</p><p>When I get an email from a person whom I have interacted with at a professional level, my immediate response is "well of course, it will be my pleasure, send them my details." When I get an email from some who says "We were on the same project" or "Hey, I took your class and got an A (or whatever)" can I get a reference, my response is sadly "Sorry, but I have not had a chance to learn about you to provide a meaningful reference."</p><p>The purpose of a reference is to let the potential employer learn that they have a strong candidate, why they should hire, and what are the things they need to be aware of and accommodate. It is for them to decide if they are the right place for the candidate and if the candidate is the right person for their team. To make this efforts a success the candidate needs strong and honest recommendations. Such recommendations should include details about their interests, passion, key strength, how they approach problem solving, their emotional and intellectual maturity, ability to interact with others, how they work as a team, and so many other things. Praising how well someone may have done, in a course or at a job, will fall flat without supporting details that evaluators often look for.</p><p>We all need references from time to time. But, well before that time we need to focus on building a professional relationship. I am not saying we need to build a relationship in order to get a reference. References are good side-effects of building a good professional relationship. Build a professional relationship, each day, and it may come in handy if and when you need a reference.</p>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com1tag:blogger.com,1999:blog-3088609713768060708.post-28250126229335065022021-01-02T12:19:00.046-07:002021-12-28T12:06:43.222-07:00PaL Series<h1>Pair and Learn (PaL) Series</h1>
<p>Venkat invites you to be part of the PaL (Pair and Learn) Series.</p><p><b>What is it?</b></p><p>Schedule a 2-hours session to pair with Venkat.</p><p><b>Why?</b></p><p style="text-align: center;"><i><b>Knowledge is the only wealth that grows when shared.</b></i></p><p>Pairing is a great way to learn from each other. We can share our knowledge, explore and validate ideas, leave the session smarter than we came in.</p><p><b>How does it work?</b></p><p>Venkat will pair with a developer for 2 hours each week.</p><p>You can schedule your week here:</p><p><a href="https://docs.google.com/forms/d/e/1FAIpQLSe04JWpdwY4XSD-_hauGUxx-sN8McWwwdpfZ88pNq2EmjUOZA/viewform?usp=sf_link" target="_blank">Schedule</a><br /></p><p>Currently schedule is open for the third quarter of 2021. Schedule for 4th quarter will be posted on September 1st. <b>(All slots for the Q2 have been taken, thank you for those who have signed up).</b></p><p>Once you schedule, Venkat will get in touch over email, about two weeks ahead, to decide the time that is convenient.</p><p><b>How to get ready?</b></p><p>Get ready to connect at the scheduled time over a link that will be provided. Please make sure your audio and camera work well. Be ready to share screen so we both can jointly work on code.</p><p><b>Cost?</b></p><p>Free.</p><p><b>Questions?</b></p><p>Please contact at <a href="https://agiledeveloper.com/contactus.html" target="_blank">https://agiledeveloper.com/contactus.html</a></p><p>Thank you</p><p><b>How is it going?</b></p><p><b>December 28</b></p><p>MM from Serbia</p><p>MM came well prepared with a lot of very interesting things to discuss. The entire 2 hours (and some) flew by so fast. We talked about learning, improving ourselves and the team, about agile development, being realistic, about stories and how to divide them, estimation, time, quality, how to practice test driven development and when, about motivating ourselves and others to continuously learn and improve. We touched on quite a lot more than these as well. Overall, it was a great way to wrap up this series.</p><p>Thanks to everyone who participated.</p><div><br /></div><p><b>December 20</b></p><p>PP and team</p><p>We discussed DDD and Event sourcing by digging into a couple of microservices the team has been prototyping as a way to explore these ideas. Very exciting discussions and perspectives.</p><p><b>November 27</b></p><p>AU from Detroit</p><p>Dived into how to approach driving design using tests. We work though an example from strategic to tactical design.</p><p><b>November 21</b></p><p>NS, VA, and AP from Minneapolis</p><p>The discussions today took us through a variety of topics. We started with a discussion around Cloud infrastructures and hosting, then went into microservices, orchestration, architecture, focusing on security, how to make technical decisions on different architectural and design front, the challenges of implementing reactive solutions, experiences around such efforts, how do we approach implementing time consuming user stories, and how to help organization be agile instead doing agile. It was a lively discussion and was a pleasure hearing from three developers about their journeys, challenges, and successes.</p><p><b>November 20:</b></p><p>Paring with WD from Germany</p><p>Can you imagine talking about "single responsibility" for a full two hours? This was one of the most exciting sessions so far and I am so glad for this particular topic. We started with the question of the scope of single responsibility. Our conversation took us through so many places, technical details, philosophical areas, management of software development, developers, their passion, their objectives, different factors that influence our decisions, about strategic and tactical decisions, monoliths, service-oriented architecture, microservices, and so many more. This can be such a great topic for a discussion session at a conference.</p><div><br /></div><p><b>September 20</b></p><p>Pairing with WA from Germany</p><p>We focused on coroutines in general and Kotlin in particular. We dived in to understand the nature of coroutines, continuations, the behavior of asynchronous code. We looked at some code examples and then the implementations at the bytecode level to support some of the behaviors exhibited by the code. The topic eventually rolled over to automated testing in the context of coroutines and the related challenges.</p><p><b>August 14</b></p><p>Pairing with VH from Chennai</p><p>This session was for about 65 minutes but we covered a number of topics. We started with a discussion on migrating to functional programming style for large enterprise applications, how to approach that. Then we discussed about how to choose between running sequentially vs. running in parallel, what are the consequences of making those decisions. We looked at a code example and discussed the merits of running sequentially and at what point we may consider switching to run in parallel. We then move on to discussions around exploring data structures available in the standard library vs. other libraries and to what extent do we need to know about different solutions and to what depth. This took us to discussions around how to learn a new language, a new library, or a framework. Whereas we can try to read about these, what other approaches we can take to get really good at technologies we're not familiar with. Along those lines how do we decide what areas we should be focusing on, should we let our curiosity drive, are there other considerations we should include in making the decision. The final topic we discussed was for a team to choose the right technology for their product, what goes into those architectural decisions.</p><p><br /></p><p><b>July 31</b></p><p>Paring with HD from Pune</p><p>This session was intriguing in many ways. First, we had a great number of discussions for a full three hours and incidentally this was the second PaL session in the same day for me. We started about learning, keeping up with change, adapting to technology. After a healthy discussion about it, we dived into talking about concurrency, the problem, the solution, the ensuing complexities. We then focused on design patterns and some of the alternative ways to apply the patterns. We refactored a small piece of code that was driving the design using a pattern, addressed some constraints, and reworked the solutions. There were quite a few more topics we discussed in between. This session was also different in that we had a few more people join the discussion midway, to listen in on the conversations. So, some of the questions were directed more broadly to be relevant for the small group.</p><div><br /></div><p><b>July 31</b></p><p>Paring with LY from Chechen Republic</p><p>Today's session was mostly directed towards architecture and design. We started out with a discussion of separating architectural concerns from design concerns. With a focus on how do we discern between the two, we looked into examples of one over the other and some areas where the lines may blur. We then talked about the challenges of evolving schema during development, some of the techniques LY has used, and the consequences of those solutions. We then discussed about the challenges of automated testing and the state of affair in our industry. We concluded with a discussion of the asynchronous programming in Python, the libraries, and diving into their implementations from the poing off view of knowing one level below the level of abstraction that we work on.</p><div><br /></div><p><b>July 16</b></p><p>Paring with IA from Nagpur</p><p>This was quite an enlightening session, entirely focused on design. We took a problem and discussed about how we will approach the design. We focused on how to create lightweight and minimalistic design, how to evaluate the extent and the timing of application of principle and patterns in the design. We were able to tease out different ideas and discuss the tradeoffs. The latter part of the discussion touched on programming paradigms, when to choose reactive apis and the benefits, DDD, and event based programming.</p><div><br /></div><p><b>June 28</b></p><p>Paring with HT from Portugal</p><p>This session was a dive into Reactive programming with Spring. HT comes with a good experience in Vert.X and event drive programming and was very curious about how Reactive Programming in done using Spring. We spent the first ten minutes or so talking about what makes an application Reactive. Then we dived in and created a sample application, a server side that emits Mono and Flux, streamed data, consumed it from a few different clients, observed the threading, non-blocking, asynchronous execution, and also looked at backpressure. Along the way we discussed use case where we can apply some of these ideas.</p><div><br /></div><p><b>June 16th</b></p><p>Paring with RM from Pensilvania</p><p>The topics for today focused around designing for microservices and driving development using automated tests. We discussed about the challenges that organizations that are used to building monoliths face in transitioning to microservices. The focus on design principles that may make good sense for monoliths may not apply directly or to the same measure when transitioning to microservices. We discussed how to help the team to see tradeoffs and place priorities where appropriate. Then we discussed writing automated tests and related challenges, working with legacy code, and how to improve the tests for existing code.</p><p><br /></p><p><b>May 30th</b></p><p>Pairing with AS from Germany</p><p>This session was quite different from a lot of other sessions so far, but nevertheless very interesting. We focused on evolutionary architecture and design, how to address the every increasing pressure to deliver solutions while the application begins to rot. How to keep up with change as the system size grows. A lot of our discussion focused on both the technical aspects of development but also the human aspects as well. We concluded the session with discussions around continuous learning. One common theme that emerged in the discussion was the need to consider tradeoffs, how so many things both in technology and life, are full of balancing between choices.</p><div><br /></div><p><b>May 29</b></p><p>Pairing with VR from Kerala</p><p>We spent about 2 hours and 15 minutes on this session, but we both had a great time. We discussed different topics, functional programming and exception handling, reactive streams API. After discussing the concepts and approaches, we dived into a Spring application that VR has been working on as a side project and spent a good part of time refactoring the code, discussing the reasons to rework some of the parts of the design. We then took another problem that VR had implemented in functional style, did a review of the code and refactored that as well, while keeping the essence of the functional approach. Overall, it was a great learning experience for both of us.</p><p><b>May 22</b></p><p>Pairing with SP from Kerala</p><p>This was a great opportunity to step away from writing code to measuring, monitoring, and testing scale and performance of code. SP is working on creating a set of tests to measure the performance of an ecommerce application. We dived into looking at the efforts that has been put in and discussed the things that could be improved. We ran a few tests, looked at the various ways the metrics are currently being gathered, analyzed, and visualized. We then discussed about some ways to express some of the tests in a more declarative and fluent ways.</p><p><b>May 9th</b></p><p>Pairing with RM and SS from Ottawa</p><p>As developers of multiple open source projects, RM and SS were very keen on taking a look at what they have done, what they could do better, the approaches to take moving forward. We have a good set of discussions around many topics including the scope of the libraries, modualizing, maintenance, being consistent across libraries, proper governance of the libraries, and many more topics. I had a great time listening to passionate developers who are genuinely interested in creating software for the community and are eager to make that effort fruitful for the communities.</p><div><br /></div><p><b>April 13 for the week of April 18</b></p><p>Pairing with JS from London</p><p>We started about 15 minutes late since I was running late from a client meeting. I thank JS for the patience. We had a great time diving into multiple area, with the conversation centered about automated testing, technical competency in teams, influencing change, working effectively with multiple people with different desires, personalities, and goals. We talked about dependency injection, approaching design from the point of view of testing vs. extensibility, and how to approach refactoring legacy applications. Overall it was a productive conversation.</p><p><br /></p><p><b>April 24</b></p><p>Paring with HR from Pune</p><p>It was a pleasure discussing about various topics with HR who I think is an outlier. Nearing graduation, HR has a lot of interesting ideas and experience with very many topics and is getting ready to start an outstanding career in software development. We talked about the use of ORM, about how much to rely on it, when and where, we then discussed about challenges in meeting requirements, the spirit of agility and how to embrase changed. We wrapped up with discussions about the challenges of using test driven development, why it is quite hard for teams to make use of it even though the benefits may seem so obvious. I am excited to see the path ahead for this young developer.</p><p><b>April 7 for the week of April 11: </b></p><p>Pairing with MC from Amsterdam</p><p>This was an excellent hands on session unlike a number of previous one. MC came prepared with an existing verbose code and was in the middle of designing a DSL for it. I really liked the initial design and where MC was heading. MC gave a quick introduction to the problem, the domain, the context, and we got down to discussing the pros and cons of the design. We agreed on a slight change in direction, started implementing the code for the DSL, and we managed to implement a good prototype of the idea. Overall it was a good learning experience for both of us, digging into Kotlin and DSLs.</p><div><br /></div><p><b>Week of April 4:</b></p><div>Paired with AG from London.</div><div><br /></div><div>This session with AG went far beyond 2 hours, we had a good discussion and coding for a total of 2.5 hours. We discussed about stream, parallel streams, and completable future from the automated testing point of view. Though the discussion started with these three major topics, we dived quite a bit into tests and code to write automated tests and also to refactor the code to reduce some verbosity and complexity. We also discussed about using functional interfaces, writing functions within functions instead of writing them as methods, the pros and cons of that approach. Overall a very fruitful session and the time flew by sop fast.</div><div><br /></div><p><b>Week of March 28:</b></p><p>LH had to cancel the meeting due to personal constraints. However, an unplanned session ensued with OA and it ran for a good 3 hours. OA approached with a Spring application where a service was transforming data which had three levels of hierarchy. OA had written it using functional style, but was not happy with the solution, and wanted to know if there are better ways. We started by writing automated tests for the existing code. Once all the tests passed, we refactored it to simplify the code. Then decided to try two other alternatives for the same code. Seeing the tests pass for the four different versions was heartwarming. We compared and contrasted the four working solutions in front of us, for elegance, simplicity, ease of understanding.</p><p><b>Week of March 21:</b></p><p>Did not hear from JM who signed up.</p><p><b>Week of March 14:</b></p><p>Pairing with AJ from Seattle</p><p>We focused on automated testing, discussed about the various type of testing, integration, system, unit testing, etc. We then took a sample problem and dived into writing automated tests while discussing some principles, rules, and approaches. Finally we took a piece of code that AJ is working on and looked at test driving the implementation of a change to the feature. A nice way to start the early morning of this years daylight savings time.</p><div><br /></div><p><b>Week of March 7:</b></p><p>Pairing with MG from Milan:</p><p>When MG sent a list of topics to discuss I was thinking it will need seven days to get through, but it one one of most enlightening discussions I should say. We started by discussing modularizations, going from monoliths to modularization enroute to possibly microservices. We dived into what are better ways to create modules, we discussed the packaging, boundaries, cohesion in terms of design and architecture. We then discuss about test driven development, the approaches for testing, about mocking and stubbing. We eventually drilled into code looking at an example of design using Kotlin. Little did we know that this code example will quickly help us related to the details we had spent the time talking. We were able to make some changes to code and work with some design alternatives and ideas, tying the changes back to the concepts we had discussed. Overall it was an exhilarating sessions, a great way to end the week.</p><p><b>Week of February 28:</b></p><p>Did not hear from GG who signed up.</p><p><b>February 27:</b></p><p>Pairing with NA from Hyderabad</p><p>The topics today ranged from issues with performance and how or how not concurrency will help, we delved then into agile development for a short while, future of programming, and programming languges. When it comes to performance, we worked on a small example to improve the speed of execution for a computation, and then explored how increasing threads, but only within limits can actually provide better performance. We then discussed about other options beyond multithreading that may help to improve performance.</p><p><br /></p><p><b>February 14:</b></p><p>Pairing with SY from Dublin on Spring Boot with Kotlin</p><p>Can there be more fun than spend the morning of a Valentines day digging into code with someone who is passionate about the craft. SY has been applying several good software practices in the financial industry. It was great listening to the experience and the journey. Then we divided into Spring Boot and Kotlin. We looked at the code SY had written to work with Mongo and we dived into Kotlin and coroutines in the context of Spring Boot applications. We dug into the debugger, looked into threads and coroutines, discussed about the impact the code has on scale and resources. The 2 hours and ten minutes went by too quickly, but we both had a good time.</p><p><br /></p><p><b>February 7:</b></p><p>Pairing with DS from Minnesota </p><p>The two hours went by quite fast, yet again. The discussions with DS were around leading change in organization related to TDD, the benefits and the challenges of taking the team through the journey to embrace the approach. We discussed about legacy systems vs. greenfield development, challenges of taking code written by other teams and continuing development. Apart from that, we discussed the trends and the challenges, understanding how microservices are being built while keeping an eye on the benefits to the business. We concluded with discussions on threading vs. asynchronous programming.</p><p><b>January 31:</b></p><p>Pairing with GR from Berlin</p><p>Two hours with a polyglot programmers, can't ask for anything better to start a week. Being a fullstack developer, GR has been digging into many languages, libraries, and frameworks for both the frontend and the backend. With a special liking for functional thinking, our discussions centered around effecting technical change, how to help developers adapt to functional programming, how to deal with challenges that we run into. We discussed about OOP with FP instead of vs, we dived into discussions about design patterns in FP, the strengths and weakness of FP, ways to deal with exceptions and impurities, when imperative may be a better choice, and many more. Two hours are beginning to feel too short for these sessions. As they say, "time flies when you're having fun."</p><p><br /></p><p><b>January 24:</b></p><p>Pairing with HC from Salt Lake City.</p><p>That was a lot of fun, the two hours flew by like a minute. It is wonderful to interact with a developer who is very keen on developing and improving the skills. We dived mostly into design concerns for high performance systems, things we should focus on, the ities to think about in architecture, scale, performance, tradeoffs. We discussed issues with cores, threads, latency, designing APIs, the pathway to automation of business process, and a few more things.</p><p>Looking forward to pairing with GR on next Sunday.</p><p><b>January 17, 2021:</b></p><p>Pairing with DP from Pensilvania.</p><p>We spent about 45 minutes on this session looking into functional thinking, what does it mean to program in functional style. We discussed about how to approach a problem from the imperative vs. a functional style of programming. Looked at some examples of transformation of data, partitioning, grouping, etc. Then we discussed the challenges of being an effective architect, how to cope up with continuous change, how to approach learning and applying.</p><p>Looking forward to pair with HC on January 24th.</p><p><b>January 10, 2021</b>:</p><p>Scheduled to pair with VU this week. The meeting was postponed as something came up in the last minute for VU. Looking forward to reschedule.</p><p><b>January 3, 2021</b>:</p><p>Pairing with GG from Hyderabad.</p><p>GG is a programmer keenly interested in networking, real-time applications, and performance. We started with a good discussion of real-time and near-time computing, why some applications scale and others don't. We talked about Erlang, Java, multithreading, how project Loom will solve some of the issues that GG so nicely identified.</p><p>We discussed about blocking vs. non-blocking calls, about Future, CompletableFuture, Reactive API, RSocket, gRPC, and a few more things.</p><p>We then dived into some code examples using RSocket. We looked into performance and scale, and fiddled with threading options.</p><p>Overall it was a nice hour and 45 minutes of discussions. In spite of such a short notice, I was pleasantly surprised how prepared GG was with questions and also examples to play with.</p><p>Looking forward to the next week pairing session with VU.</p><div><br /></div>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com0tag:blogger.com,1999:blog-3088609713768060708.post-85509192721791196962020-08-03T07:52:00.003-06:002020-08-03T08:12:29.513-06:00Update: Starting sixth month of stay at home<div dir="ltr" style="text-align: left;" trbidi="on">
- revenue down sharply<br />
- loss from cancelling conference<br />
<br />
* keeping up with usual charity donations, thanks to companies that have hired me during these hard times<br />
* offering free videos to anyone looking for a job: <a href="http://blog.agiledeveloper.com/2020/05/learn-while-you-look-for-job.html">http://blog.agiledeveloper.com/2020/05/learn-while-you-look-for-job.html</a><br />
* have kept up speaking at user groups, albeit mostly online<br />
<br />
+ in much less pain than usual, spending less money on injections and treatments<br />
+ spending more time with family, I'm very thankful for that<br />
+ working on a new book on DSL in Kotlin<br />
+ lost about 10lbs/4.5kg<br />
+ doing a lot more hiking than usual<br />
+ learning more each day<br />
+ offering live classes, at least a couple of days each week: <a href="https://www.agilelearner.com/live">https://www.agilelearner.com/live</a><br />
+ spending more time mentoring developers online<br />
<div>
<br /></div>
<div>
How are things going for you?</div>
<div>
<br /></div>
</div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com4tag:blogger.com,1999:blog-3088609713768060708.post-5983612436492068332020-05-09T09:29:00.004-06:002021-07-05T07:21:00.105-06:00Learn while you look for a Job<div dir="ltr" style="text-align: left;" trbidi="on">
<h3>Learn for free while you look for a job. For details, please click on </h3><h3><a href="https://bit.ly/35JIhV2"><strike>https://bit.ly/35JIhV2</strike></a></h3><div dir="ltr" trbidi="on"><br /></div><div dir="ltr" trbidi="on"><b>Update:</b></div><div dir="ltr" trbidi="on">This was initiated on May 9, 2020. As of January 5, 2021, a total of 638 developers have signed up for this. Hope it has been and continues to be useful as we get through these hard times.</div><div dir="ltr" trbidi="on"><br /></div><div dir="ltr" trbidi="on">Update July 5, 2021</div><div dir="ltr" trbidi="on">A total of 685 developers took this opportunity. Hope that was useful. Best wishes to everyone.</div><div dir="ltr" trbidi="on"><br /></div><div dir="ltr" trbidi="on">This offer has ended.</div><div dir="ltr" trbidi="on"><br /></div></div>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com2tag:blogger.com,1999:blog-3088609713768060708.post-83142741573847960632020-03-21T09:15:00.000-06:002020-03-21T09:17:03.545-06:00Something surprising happened<div dir="ltr" style="text-align: left;" trbidi="on">
<p>I am deeply humbled by the generous acts of some developers.</p>
<p>On March 14th I <a href="https://twitter.com/venkat_s/status/1238983023585939457">tweeted and posted on Linkedin</a> that I am offering subscription to agilelearner totally free for one month.</p>
<p>Soon after that, I am thankful, several people signed up for the complimentary membership.</p>
<p>Then, almost a day later, I noticed something that I was not expecting. Some developers started purchasing subscription. That is right, they did not want it for free, they wanted to pay for it. It started on the day after post and has continued. It was as if these developers were sending me a message of solidarity.</p>
<p>I am very grateful to each and everyone who paid for the subscription. I was not expecting anyone to subscribe and this truly came to me as a surprise. Thank you, you have certainly restored my faith in the society. These are tough times for many and, however little we can, we should support those who are less privileged than we are.</p>
<p>I will be donating the entire revenue from the subscriptions between March 14th and April 15th, 2020 towards COVID-19 support.</p>
<br /></div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com6tag:blogger.com,1999:blog-3088609713768060708.post-22590621072713407182020-01-07T05:21:00.000-07:002020-01-07T05:37:28.367-07:00dev.next 2020 Conference Program Announced<div dir="ltr" style="text-align: left;" trbidi="on">
<p>About 20 years ago I gave my first conference talk. I will never forget those first moments—it was a great experience to learn from the legends of the time. After speaking in hundreds of conferences I have decided to take some of those experiences and apply towards running my own conference. I have a lot more to learn, but it has been a rewarding learning experience already.</p>
<p>My main objective in creating the <a href="https://www.devdotnext.com">dev.next Conference</a> is to bring both experienced and aspiring speakers together, to deliver high quality technical content for developers eager to learn and improve their software craft. The journey is not easy but I am very grateful for all the help I have received so far, from the software communities, experts in the industry, and other conference organizers.</p>
<p>An independent <a href="https://www.devdotnext.com/people">program committee</a> evaluated the proposals and speakers were chosen based solely on technical merits. From among 460 proposals, about 150 proposals were selected.</p>
<p>You can find the Program for the conference at <a href="https://www.devdotnext.com/program">https://www.devdotnext.com/program</a>.</p>
<p>I invite you to register for the conference at <a href="https://www.devdotnext.com/register">https://www.devdotnext.com/register</a>.</p>
<p>Get $50 off with coupon code LEARN</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-7nPeHqIo60k/XhR3iOa0zUI/AAAAAAAAAgU/WOukkFJ4Pd4d8JKGspXIKfxcNg4mRRbsgCLcBGAsYHQ/s1600/devdotnextimg.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-7nPeHqIo60k/XhR3iOa0zUI/AAAAAAAAAgU/WOukkFJ4Pd4d8JKGspXIKfxcNg4mRRbsgCLcBGAsYHQ/s320/devdotnextimg.png" width="320" height="180" data-original-width="1000" data-original-height="563" /></a></div>
</div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com1tag:blogger.com,1999:blog-3088609713768060708.post-48299500603111118852018-06-27T05:11:00.002-06:002018-06-27T05:14:36.955-06:00Rediscovering JavaScript book release<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="https://twitter.com/share" class="twitter-share-button" data-text="Rediscovering JavaScript book release" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<table>
<tr>
<td>
<h2>From the back cover of the book</h2>
<p>"JavaScript is no longer to be feared or loathed—the world’s most popular and ubiquitous language has evolved into a respectable language. Whether you’re writing frontend applications or server-side code, the phenomenal features from ES6 and beyond—like the rest operator, generators, destructuring, object literals, arrow functions, modern classes, promises, async, and metaprogramming capabilities—will get you excited and eager to program with JavaScript. You’ve found the right book to get started quickly and dive deep into the essence of modern JavaScript. Learn practical tips to apply the elegant parts of the language and the gotchas to avoid."</p>
<h2>Who is the book for</h2>
<p>The book has something for beginners and experienced alike. If you're new to the modern features of JavaScript, the book will walk you through a number of powerful and useful features you can immediately put to use. If you have good experience with JavaScript, parts of the book like metaprogramming will intrigue you to take your expertise to the next level.</p>
<h2>Where can you order</h2>
<ul>
<li>Printed, PDF, DRM free Ebook (different formats) from <A href="https://pragprog.com/book/ves6/rediscovering-javascript">Pragmatic Programmers website</A>.</li>
<li>Printed version from <A href="https://www.amazon.com/Rediscovering-JavaScript-Master-ES6-ES7/dp/1680505467">Amazon.com</A></li>
</ul>
</td>
<td width="30%">
<A href="https://pragprog.com/book/ves6/rediscovering-javascript">
<img src="https://agiledeveloper.com/images/ves6.jpg" width="300" height="300"></A>
</td>
</tr>
</table>
</div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com2tag:blogger.com,1999:blog-3088609713768060708.post-51021319093678278892018-05-15T16:35:00.003-06:002018-05-15T17:23:57.243-06:00I'm blessed, deeply humbled, and very thankful<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<a class="twitter-share-button" data-size="large" data-text="I'm blessed, deeply humbled, and very thankful" href="https://twitter.com/share">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
Today I finish what started almost 11 months ago—traveling to 50 user groups, to interact with developers, share the little I know, and learn from them in the process.<br />
<br />
It all started on June 23rd, 2017, on a train ride. <a href="https://twitter.com/prondzyn">Piotr Prądzyński</a> had <a href="https://www.meetup.com/Torun-JUG/events/240063320">organized a Java Day</a> in Toruń, Poland and invited me to speak there. I was traveling from Kraków, after speaking at <a href="http://devoxx.pl/">Devoxx, Poland</a>, by train. It was about ten days after my 49th birthday. That's when a thought sparked in my mind: what if I turn this year ahead, with this talk I was going to give the next day as the first of 50 presentations within a year, to celebrate my 50 years on this planet.</div>
<br />
It was early in the morning in the US at that time and so I decided to wait, to consult with my wife, Kavitha, after she woke up. When I heard from her, I texted: "Hey, what if I speak in 50 user groups, around the world, to celebrate this 50th year?"<br />
<br />
There was silence for a minute, and then I got the response: "That's a great idea."<br />
I was not sure what that means? Was it "Yay, that is awesome, go for it." or was it a response like "yeah, right."<br />
<br />
So, I did not respond, just grimaced for the next few minutes. Then I saw several text messages from her—many suggestions on how I could do it, words full of encouragements and advices. It was great to get that OK from the most important person of all.<br />
Then, the doubt kicked in. Is this really possible? Generally I speak in about a <a href="https://agiledeveloper.com/conferences.html">dozen user groups each year</a>. This is more than 4 times that. What about the cost of travel? How to approach the user groups? That was an interesting but crazy idea. Forget it.<br />
<br />
I stared through the window of the moving train for a few minutes. Then I emailed separately both Piotr and <a href="https://twitter.com/grzegorzduda">Grzegorz Duda</a>, the organizer of Devoxx, Poland, to see what they thought. Soon they both responded that it was a great idea and I should do it. They should not have given the encouragement and I should not have listened. Now there was nothing to stop this crazy little guy.<br />
<br />
Within minutes I <a href="http://blog.agiledeveloper.com/2017/06/a-small-man-with-big-aspiration-tour.html">blogged about it</a>, listing a couple of user groups I had already scheduled for the coming months. Then everything went quiet...<br />
<br />
A day later the emails started coming, from user group leaders, passionate developers, conference organizers, and many more. Within a few weeks I had well over 37 user groups that had signed up. I was overwhelmed by the support and am sincerely thankful.<br />
<br />
Through the user groups, <a href="http://blog.agiledeveloper.com/2017/06/a-small-man-with-big-aspiration-tour.html">many companies and conferences sponsored (please see the full list at this link)</a> the user group meetings, paid for my travel and accommodation. I could not have done this definitely without the help of the sponsors. Many thanks to each one of them.<br />
<br />
Here are the 18 countries that I had a chance to speak in for this tour: Austria, Belgium, Canada, France, Germany, India, Ireland, Italy, Lithuania, Norway, Poland, Slovakia, Spain, Sweden, Switzerland, The Netherlands, The United Kingdom, and The United States.<br />
<br />
A few decades ago, the opportunity to speak at a conference came from me speaking at a user group, specifically the <a href="http://www.hjug.org/">Houston Java Users Group</a>. I can't say "no" when a user group invites me to speak and I often reach out to user groups when I am in a nearby city. The 50-50 tour will continue beyond 50, until my birthday in June. I sincerely hope to continue to speak at user groups as long as groups want me to speak.<br />
<br />
Within a couple of weeks after I blogged back in June, 2017 <a href="https://twitter.com/josepaumard">José Paumard</a> reached out and wanted me to speak at the 10th anniversary of the <a href="https://twitter.com/parisjug">Paris JUG</a> in May 2018. Here we are, thanks to José! What a great coincidence. It is the 10th anniversary celebration of the JUG in La Ville-Lumière (The City of Lights) and it is also the 50th user group in this tour. Plus, the location that <A href="https://www.twitter.com/kanedafromparis">Charles Sabourdin</A>, The President of the ParisJUG picked for the presentations and the celebrations is unmatchable—<a href="https://www.parisjug.org/xwiki/wiki/oldversion/view/Meeting/20180515">The Eiffel Tower</a>.<br />
<br />
<img height="225" src="https://pbs.twimg.com/media/DdOlU4aVQAEgsrk.jpg:large" width="300" />
<img src="https://pbs.twimg.com/media/DdPeaVfW4AAhjUK.jpg:large" width="300" />
<img height="225" src="https://pbs.twimg.com/media/DdPc4hTX4AE35GT.jpg" width="300" />
<br />
<br />
I am blessed and very thankful.<br />
<br />
I met so many developers on this tour, made so many friends, I was able to see their joy, their passion, and also hear about their struggles. It made me realize once more, behind all the code we write, there's that wonderful person whose daily struggles and stories is what makes that code so much more special.<br />
<br />
Thank you to everyone who made this crazy thought a reality.<br />
<br />
I am very grateful to all the user group leaders who were so welcoming and generous to have me at their group. Special thanks to:<br />
Piotr Prądzyński (<a href="https://twitter.com/prondzyn">@prondzyn</a>), Toruń JUG <br />
Garry Hessler, Colorado Springs JUG<br />
Erik Weibust (<a href="https://twitter.com/erikweibust">@erikweibust</a>), Dallas Metroplex JUG<br />
Bruce Alspaugh (<a href="https://twitter.com/alspaughb">@alspaughb</a>), St. Louis JUG<br />
Nimret Sandhu (<a href="https://twitter.com/n1mr37">@n1mr37</a>), Seattle JUG<br />
Scott Kramer (<a href="https://twitter.com/IllinoisJUG">@IllinoisJUG</a>), Illinois JUG<br />
Chiu-Ki Chan (<a href="https://twitter.com/chiuki">@chiuki</a>), Google Developer Group, Boulder<br />
Barry Evans (<a href="https://twitter.com/bazza_ni">@bazza_ni</a>) and Barry Alistair, Dublin JUG<br />
Bert Jan Schrijver (<a href="https://twitter.com/bjschrijver">@bjschrijver</a>), The Netherlands JUG (NLJUG)<br />
Christoph Strobl (<a href="https://twitter.com/stroblchristoph">@stroblchristoph</a>), eJUG Austria <br />
Adrian Nowak (<a href="https://twitter.com/adrno">@adrno</a>), Polish JUG<br />
Artur Owczarek (<a href="https://twitter.com/owcartur">@owcartur</a>), Warsaw JUG<br />
Marcin Swierczynski (<a href="https://twitter.com/" marcinos85="">@marcinos85</a>), Silesia JUG<br />
Simon Maple (<a href="https://twitter.com/sjmaple">@sjmaple</a>), vJUG<br />
Victor Duran (<a href="https://twitter.com/hiqinternat">@hiqinternat</a>) and Mattias Karlsson (<a href="https://twitter.com/matkar">@matkar</a>), Stockholm JVM group and JForum<br />
Jonas Andersson (<a href="https://twitter.com/tradjonas">@tradjonas</a>) and Mattias Sällström (<a href="https://twitter.com/msallstr">@msallstr</a>), Umeå JUG<br />
Jim Bethencourt (<a href="https://twitter.com/jimbethancourt">@jimbethancourt</a>), Houston JUG<br />
Dervis Mansuroglu (<a href="https://twitter.com/dervis_m">@dervis_m</a>), JavaBin Oslo<br />
Olivier Hubaut (<a href="https://twitter.com/ohubaut">@ohubaut</a>), Brussel JUG<br />
Kasparas Rudokas (<a href="https://twitter.com/ralkie">@ralkie</a>), Vilnius JUG<br />
Muhammad Swalah (<a href="https://twitter.com/swalahamani">@swalahamani</a>), Kerala JUG<br />
Buddha Jyothiprasad (<a href="https://twitter.com/prbuddha">@prbuddha</a>) and Rohit Vaidya (<a href="https://twitter.com/nerdyrohit">@nerdyrohit</a>), Hyderabad JUG. Special thanks to Rajmahendra (<a href="https://twitter.com/rajonjava">@rajonjava</a>).<br />
Thamizharasu (<a href="https://twitter.com/zarub2k">@zarub2k</a>), Madras JUG<br />
Jitendra Chittoda (<a href="https://twitter.com/JChittoda">@JChittoda</a>), Mala Gupta (<a href="https://twitter.com/emalagupta">@emalagupta</a>), Steve Mann (<a href="https://twitter.com/stevemann2705">@stevemann2705</a>), et. al., Delhi JUG<br />
Shaun Chung, Tampa JUG<br />
Marcelo Olivas (<a href="https://twitter.com/mfolivas">@mfolivas</a>), Miami JVM Group<br />
Pratik Patel (<a href="https://twitter.com/prpatel">@prpatel</a>) and Vincent Mayers (<a href="https://twitter.com/vincentmayers">@vincentmayers</a>), Atlanta JUG<br />
Arun Gupta (<a href="https://twitter.com/arungupta">@arungupta</a>) and Van Riper (<a href="https://twitter.com/vanriper">@vanriper</a>), Silicon Valley JUG<br />
Matt Raible (<a href="https://twitter.com/mraible">@mraible</a>) and Greg Ostravich (<a href="https://twitter.com/gregostravich">@gregostravich</a>), Denver JUG<br />
Stevel Lintz, New England JUG <br />
Henri Tremblay (<a href="https://twitter.com/henri_tremblay">@henri_tremblay</a>), Montreal JUG<br />
Marcus Fihlon (<a href="https://twitter.com/mcpringle">@mcpringle</a>), Luzern JUG<br />
Marcus Fihlon (<a href="https://twitter.com/mcpringle">@mcpringle</a>), Bern JUG<br />
Marcus Fihlon (<a href="https://twitter.com/mcpringle">@mcpringle</a>), Basel JUG<br />
Marcus Fihlon (<a href="https://twitter.com/mcpringle">@mcpringle</a>), St. Gallen JUG<br />
Marcus Fihlon (<a href="https://twitter.com/mcpringle">@mcpringle</a>), Zürich JUG<br />
Wolfgang Schell (<a href="https://twitter.com/jetztgradnet">@jetztgradnet</a>), Mannheim JUG<br />
Ravinder Jilkapally and Matt Schuetze (<a href="https://twitter.com/schuetzematt">@schuetzematt</a>), Detroit JUG<br />
Simone Bordet (<a href="https://twitter.com/simonebordet">@simonebordet</a>), Torino JUG<br />
Mario Fusco (<a href="https://twitter.com/mariofusco">@mariofusco</a>), et. al., Milano JUG<br />
Dušan Trávniček (<a href="https://twitter.com/">@</a>), Eastcode Session, košice.<br />
Michael P. Redlich (<a href="https://twitter.com/mpredl">@mpredl</a>), ACGNJ JUG<br />
Frank Greco (<a href="https://twitter.com/frankgreco">@frankgreco</a>) and Chandra Guntur (<a href="https://twitter.com/CGuntur">@CGuntur</a>), NYC JUG<br />
Billy Korando (<a billykorando="" href="https://twitter.com/">@BillyKorando</a>), Kansas City JUG<br />
Christopher M. Judd (<a href="https://twitter.com/" javajudd="">@javajudd</a>), Columbus JUG<br />
Craig Castelaz (<a href="https://twitter.com/JavaCleveland">@JavaCleveland</a>), Cleveland JUG<br />
Vaibhav Choudhary (<a href="https://twitter.com/vaibhav_c">@vaibhav_c</a>), Bangalore JUG<br />
Dominique Carlo and Simon Maple (<a href="https://twitter.com/sjmaple">@sjmaple</a>), London JUG<br />
Patrizio Munzi (<a href="https://twitter.com/patrizio_munzi">@patrizio_munzi</a>), Rome JUG<br />
José Paumard (<a href="https://twitter.com/josepaumard">@josepaumard</a>) and Charles Sabourdin (<a href="https://twitter.com/kanedafromparis">@kanedafromparis</a>), Paris JUG<br />
Don Bogardus and Jason Porter (<a href="https://twitter.com/lightguardjp">@lightguardjp</a>), Utah JUG<br />
Trisha Gee (<a href="https://twitter.com/trisha_gee">@trisha_gee</a>) and Israel Rodriguez(<a href="https://twitter.com/IsraKaos">@IsraKaos</a>), Sevilla JUG <br />
Dominik Dorn (<a href="https://twitter.com/domdorn">@domdorn</a>), Vienna JUG<br />
<br /></div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com3tag:blogger.com,1999:blog-3088609713768060708.post-24111303259391263022018-05-05T05:46:00.001-06:002018-05-08T07:27:17.953-06:00Definitely no intention to exclude ladies, or anyone for that matter.<div dir="ltr" style="text-align: left;" trbidi="on">
<a class="twitter-share-button" data-size="large" data-text="Definitely no intention to exclude ladies" href="https://twitter.com/share">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
It was a great pleasure to be asked to write a foreword for <a href="https://pragprog.com/book/javacomp/java-by-comparison">Java by Comparison: Become a Java Craftsman in 70 Examples</a>. The book does a great job of helping programmers write better Java code. When I sat down to write the foreword I asked myself what message I like to convey, to inspire readers who are able to take the journey through this book. Here's an excerpt of what appeared in the foreword:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-OZHygPhFuxE/Wu1ns7qWmnI/AAAAAAAAAZw/bMJN-vfvceQkbjKMpXebnsGpFtlm0q05QCLcBGAs/s1600/forwardexerpt.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="524" data-original-width="685" height="245" src="https://2.bp.blogspot.com/-OZHygPhFuxE/Wu1ns7qWmnI/AAAAAAAAAZw/bMJN-vfvceQkbjKMpXebnsGpFtlm0q05QCLcBGAs/s320/forwardexerpt.png" width="320" /></a></div>
The key message is we have to be mindful of others who come after us to maintain the code. I recently came to know that some got offended by the foreword.<br />
<br />
The writing goes through edits and English gets corrected and changed along the way. I want to assure anyone reading the foreword or any of my work that (a) I take full responsibility for what I write and (b) I can assure that I had nor have no intention of discrimination what-so-ever. In my mind at the time of writing and now, the reader of any programming book may be of any gender. It is totally silly and objectionable in my mind to suggest that the reader should be a man and can't be a woman. Some of the people who have been the most influential in my life has been my woman relatives. I would not be who I am without their attention, sacrifices, and generosity. In fact, I wrote dedication to my grandmothers in one of my books. I can't imagine myself ever thinking women somehow are less or less important. Evidence in my life has been quite different, personally to me.<br />
<br />
Let me talk about what the above paragraph says in my interpretation:<br />
<ul>
<li>It uses an example of a woman holding the door</li>
<li>It uses the reader of the book who may be of any gender.</li>
</ul>
I have seen both men and women hold doors to people behind them. I have also seen both gender not caring to do so. I almost always hold doors, sometime for a lengthy time. It is not because I think they are incapable of opening the door. It is a curtesy I appreciate when someone extends to me and I do to others with joy. I keep the door open for just about anyone, for women, men, children, elders, just about anyone irrespective of how they look, where they come from,... it does not matter.<br />
<br />
I travel a lot. I often see people dragging heavy luggage through stairs as they approach airplanes or try to place them in the overhead luggage compartment. When I see the person struggle, I often step in and ask if I can help. Sometimes I carry their luggage to their gates, even if it is out of my way. I see my relatives in them and feel that I should help. I also know it will be me in a few years who will need that help. I surely hope there are people who care to help when I am in need.<br />
Sincerely, gender does not play a role in my mind. I care to help no matter who they are, that's just my nature. I say it not to be proud of myself, I say it to state the fact that gender does not matter to me. It is the caring that matters to me and I certainly care for just about anyone.<br />
Let me talk about what the first few paragraphs in the foreword does not talk about in my interpretation:<br />
<ul>
<li>It does not exclude a man holding the door for someone. It does not say that only woman hold door and not men.</li>
<li>It does not exclude the person who the door is being held for. It could be anyone. In the example, that person walking behind is the reader, who may be anyone, of any gender, any color, just about anyone. Did I mean the person reading is a man? No. Did I mean it is a woman? No. It could be a man or a woman, anyone reading the book.</li>
<li>It does not say one gender is more benevolent than the other or does it say that only one gender does or should hold the door.</li>
<li>It does not imply that the reader has to be a man only or a woman only.</li>
</ul>
If those paragraphs offended someone I express my sincere apology. Be assured I had no intention at the time of writing nor do I have any intention now to discriminate against anyone. All I can say is, I simply do not have such discriminating thoughts. If anyone wants to interpret otherwise, I simply can't help, it is their right to interpret the way they want. If anyone wants to ask what I meant, I meant no ill will or discrimination towards anyone. I am at most thrilled to work with anyone, interact with anyone, and play a small part in their learning as much as they play in my learning.<br />
<br />
Thank you for listening.<br />
<br />
<hr />
Update (May 7, 2:34AM GMT + 3):
<br />
<br />
I’ve been in touch with the publisher and an updated foreword with the copyedit error fixed will be release very soon. I will update this blog post when the updated version of the book is released.<br />
<br />
Thank you for everyone who gave their feedback and advice. Much appreciated.<br />
<br />
My sincere apology for the error and the frustration and agony it has caused.<br />
<hr>
Update May 8, 14:25 BST:
Just got word from the publisher. They're releasing an updated eBook and sending to the printer the book with the following corrected foreword:
<div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-rmI6yqr4zKU/WvGloVTt2qI/AAAAAAAAAaQ/7WWi8JvTiNQ0A_IeY62Li5OFIj3OsieFQCLcBGAs/s1600/updatedforeword.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-rmI6yqr4zKU/WvGloVTt2qI/AAAAAAAAAaQ/7WWi8JvTiNQ0A_IeY62Li5OFIj3OsieFQCLcBGAs/s320/updatedforeword.png" width="320" height="236" data-original-width="1310" data-original-height="968" /></a></div>
Thank you.
<div>
<br /></div>
</div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com1tag:blogger.com,1999:blog-3088609713768060708.post-16274010892398474952017-12-28T08:15:00.001-07:002017-12-28T08:15:56.273-07:002017 Top Viewed Presentations @agileLearner<a href="https://twitter.com/share" class="twitter-share-button" data-text="2017 Top Viewed Presentations @agileLearner" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<p>The following were the five most viewed presentation on <A href="http://www.agilelearner.com">http://www.agilelearner.com</A> in the year 2017:
<ul>
<li><A href="https://www.agilelearner.com/presentation/2">Internal vs External Iterators</A></li>
<li><A href="https://www.agilelearner.com/presentation/194">Code Quality: Code Coverage</A></li>
<li><A href="https://www.agilelearner.com/presentation/372">Test Driven Development</A></li>
<li><A href="https://www.agilelearner.com/presentation/740">Java 8 Programming Idioms: Use Range to Iterate</A></li>
<li><A href="https://www.agilelearner.com/presentation/800">Java 8 Parallel Streams: Parallel and Filter</A></li>
</ul>
There are a total of <A href="https://www.agilelearner.com/presentation/bydate">1015 presentations</A> as of today on the site.
<p>More videos coming in 2018.</p>
<p>If you're not familiar with the site and like to get a taste of the presentations there, please check out any of the <A href="https://www.agilelearner.com/search?q=free">84 free videos at this link</A>.</p>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com0tag:blogger.com,1999:blog-3088609713768060708.post-71913841150017406802017-10-17T12:36:00.003-06:002017-10-17T12:38:56.283-06:00Always be professional when you write an email, especially to a stranger<a href="https://twitter.com/share" class="twitter-share-button" data-text="Always be professional when you write an email" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<div dir="ltr" style="text-align: left;" trbidi="on">
Each week I respond to multiple emails from software developers. Most of the emails are very professional and quite polite. I respond as soon as possible, often with as much help as I can provide.<br />
<br />
However, once every few months I would receive an email that totally upsets me.<br />
<br />
A few months back, I got an email that said something like "here is my code" tell me how to solve this. I got quite mad at the sender and responded to let him know how I felt. I let him know that even my bosses do not make demands that way and I expect such communication to have words like "request", "please," and "thanks."<br />
<br />
I truly feel terrible when I respond negatively, but I also feel terrible when people do not make the effort to be polite and professional in their communication.<br />
<br />
Today was one such day—I got an email with the subject:<br />
<br />
<b><i>urgent suggestions required</i></b><br />
<br />
The words like "Required" and "Urgent" are not good choices. Those words mean "drop everything you are doing; I demand you to reply, right now, urgently." Don't demand, request. Be sensitive to other people's time.<br />
<br />
OK, let's read further, what the sender had to say:<br />
<br />
<b><i>hello , Sir </i></b><br />
<br />
Well, that's nice. I generally request people who address me as Sir to address me by my first name, but I think that's quite professional to address a stranger that way. That was the only well written part in the entire email.<br />
<br />
The rest of the email went on to list things the person knew, in phrases (like bullet points) instead of sentences. It followed with a bullets of questions, like<br />
<br />
<b><i>"Is X good"</i></b><br />
<b><i>"Is Y good"</i></b><br />
<br />
And it abruptly ended, with no thank you, no closing words, but with on final sentence:<br />
<br />
<b><i>to be an Indian you have to help a Indian.</i></b><br />
<br />
eh? Excuse me? Really?<br />
<br />
That's so loaded, in so many ways.<br />
<br />
First, there is a demand. Second, there is an assumption that the other person may not respond. Third there is an insult. Also, you just dragged in something personal about the person, instead of keeping the conversation professional.<br />
<br />
Like I mentioned, most people who write to me have no issues communicating professionally. But, for those who may need some help here are a few tips:<br />
<br />
1. When asking someone's help, learn to be professional.<br />
<br />
2. Make sure the subject line is a request and not a demand or an insult.<br />
"require" is a demand. The word you are looking for is request. Try<br />
"I request your carrier advice" or "Could you help me by answering a few questions?"<br />
<br />
3. Avoid words like urgent. Please be sensitive to other people's time. If someone is going to respond, they will. If someone is not the kind who will respond, you did not help the situation in anyway by putting the word "urgent." You probably made it worse.<br />
<br />
4. Make sure you state your question as a request when you start the email. For example, "I would like to request some advice from you about ..."<br />
<br />
5. Write full sentences and short paragraphs. State your situation or problem using full grammatically correct sentences. Not bullet points.<br />
<br />
6. Then transition to your question. For example, "Given this background, I am wondering if I should seek a carrier in..."<br />
<br />
7. Again write in full sentences and short paragraphs, stating the options you are considering.<br />
<br />
8. Conclude with a thank you, asking the person to respond at their earliest convenience and let them know you are thankful for them spending the time answering your question. Don't get personal, and especially do not insult that person.<br />
<br />
9. Put your name after the thank you. Convey that you are a person and not a senseless robot that spews out demands.<br />
<br />
10. Ask a friend, a colleague, or a relative to read your email. For example, my children write quite a few emails to professionals asking for help, with advice, help on their projects, etc. They always ask their mom (and occasionally me) to review it before they send. We have corrected so many emails for them that now they are pretty good at sending emails on their own.<br />
<br />
After all of this, the person you write to may still not respond. But at least it will help those who do care to respond to you.<br />
<br /></div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com7tag:blogger.com,1999:blog-3088609713768060708.post-39524306799026900322017-09-13T04:00:00.000-06:002018-01-05T15:58:10.536-07:00Java 8 Programming Idioms Series at IBM DeveloperWorks<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="https://twitter.com/share" class="twitter-share-button" data-text="Java 8 Idioms" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<p>I'd like to thank <A href="https://www.ibm.com/developerworks/">IBM DeveloperWorks</A> (<A href="https://twitter.com/developerworks">@developerworks</A>) for giving me an opportunity to write.</p>
<p>It's been a pleasure writing a series of articles for IBM DeveloperWorks on the topic of <A href="https://www.ibm.com/developerworks/views/global/libraryview.jsp?series_title_by=Java+8+idioms"><i><b>Java 8 Programming Idioms</b></i></A>.</p>
<p>The series focuses on programming practices related to Java 8 lambda expressions, method references, and functional style of programming.</p>
<p>The entire series can be <A href="https://www.ibm.com/developerworks/views/global/libraryview.jsp?series_title_by=Java+8+idioms">found here</A>.</p>
<p>The links to each of the articles in the series is given below:</p>
<ol>
<li><A href="https://www.ibm.com/developerworks/java/library/j-java8idioms1/index.html">An easier path to functional programming in Java</A></li>
<li><A href="https://www.ibm.com/developerworks/java/library/j-java8idioms2/index.html">Function composition and the Collection Pipeline pattern
</A></li>
<li><A href="https://www.ibm.com/developerworks/java/library/j-java8idioms3/index.html">Functional alternatives to the traditional for loop</A></li>
<li><A href="https://www.ibm.com/developerworks/java/library/j-java8idioms4/index.html">In praise of helpful coding</A></li>
<li><A href="https://www.ibm.com/developerworks/java/library/j-java8idioms5/index.html">An alternative to passing through</A></li>
<li><A href="https://www.ibm.com/developerworks/java/library/j-java8idioms6/index.html">Why the perfect lambda expression is just one line</A></li>
<li><A href="https://www.ibm.com/developerworks/java/library/j-java8idioms7/index.html">Functional interfaces</A></li>
<li><A href="https://www.ibm.com/developerworks/java/library/j-java8idioms8/index.html">Java knows your type
</A></li>
<li><A href="https://www.ibm.com/developerworks/java/library/j-java8idioms9/index.html">Cascading lambdas</A></li>
<li><A href="https://www.ibm.com/developerworks/java/library/j-java8idioms10/index.html">Using closures to capture state</A></li>
<li><A href="https://www.ibm.com/developerworks/java/library/j-java8idioms11/index.html">Functional purity</A></li>
</ol>
<p>Hope you find the series useful. Thank you for reading.</p>
</div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com5tag:blogger.com,1999:blog-3088609713768060708.post-59642732662825058802017-06-24T03:00:00.000-06:002018-05-15T15:36:39.870-06:00A small man with a big aspiration tour: 50 user groups in a year<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<a class="twitter-share-button" data-size="large" data-text="A small man with a big aspiration tour: 50 user groups #venkat_50_50_tour" href="https://twitter.com/share">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<div>
<table>
<tbody>
<tr>
<td>The opportunity to speak at conferences for me came from speaking at user groups. That's one of many reasons I love user groups and have spoken in at least a dozen of them each year. To say thanks in a special way and to celebrate my 50 years on this planet, I have a big aspiration: I hope to speak at 50 user groups over 12 months leading up to my 50th birthday.</td></tr>
</tbody></table>
</div>
</div>
<br />
<br />
<div>
<b>Special thanks to the following sponsors:</b>
<br />
<table>
<tbody>
<tr>
<td><img height="80" src="https://agiledeveloper.com/images/nfjs2010.jpg" width="100" /></td><td><a href="https://nofluffjuststuff.com/home/main">No Fluff Just Stuff: NFJS</a></td>
<td><img height="80" src="https://agiledeveloper.com/images/devoxx_logo.gif" width="100" /></td><td><a href="http://devoxx.pl/">Devoxx</a></td>
<td><img height="80" src="https://agiledeveloper.com/images/devnexus2010.png" width="100" /></td><td><a href="https://devnexus.com/">DevNexus</a></td>
<td><img src="http://www.saltmarch.com/images/SaltmarchLogo.jpg" height="80" width="100" /></td><td><a href="http://www.saltmarch.com/">Saltmarch Media</a></td>
</tr>
<tr>
<td><img src="http://umecon.se/wp-content/uploads/2016/09/umeconlogo.jpg" height="80" width="100" /></td><td><a href="http://www.umecon.se/">Umecon</a></td>
<td><img src="http://devconf.pl/assets/img/logo.png" height="80" width="100" /></td><td><a href="http://devconf.pl/">DevConf</a></td>
<td><img height="80" src="https://agiledeveloper.com/images/logoNDC2012.jpg" width="100" /></td><td><a href="http://ndctechtown.com/">NDC Conferences</a></td>
<td><img height="80" src="https://voxxeddays.com/zurich/wp-content/uploads/sites/25/2016/08/Voxxed-Days-Logo-ZURICH_WhiteBlue_NoTransparent.jpg" width="100" /></td><td><a href="https://voxxeddays.com/zurich/">VoxxedDay Zurich</a></td>
</tr>
<tr><td><img src="http://www.blue4it.nl/images/Blue4IT-logo.png" height="80" width="100" /></td><td><a href="http://www.blue4it.nl/">Blue4IT</a></td>
<td><img src="http://agiledeveloper.com/images/hotels.jpg" height="80" width="100" /></td><td><a href="https://www.hotels.com/">hotels.com</a></td>
<td><img src="http://stackand.co/Stackandco-Typologosmall.png" height="80" width="100" /></td><td><a href="http://stackand.co/">Stack and .Co</a></td>
<td><img height="80" src="https://botw-pd.s3.amazonaws.com/styles/logo-thumbnail/s3/0002/7177/brand.gif?itok=iKwm_yv4" width="100" /></td><td><a href="https://www.equifax.com/">EQUIFAX</a></td>
</tr>
<tr>
<td><img height="80" src="https://i1.wp.com/www.cloudcredential.org/wp-content/uploads/2014/05/guruteam-logo.png?fit=270%2C240" width="100" /></td><td>
<a href="http://www.guruteamirl.com/">GURUTEAM</a></td>
<td><img height="80" src="https://sonorplex.com/wp-content/uploads/2014/04/SonorPlex-PNG-Logo-Small.png" width="100" /></td><td><a href="https://sonorplex.com/">SonorPlex</a></td>
<td><img height="80" src="https://tcubedublin.com/tcube/img/logo-dark.png" width="100" /></td><td>
<a href="https://tcubedublin.com/">tcube</a></td>
<td><img src="http://version1.com/getmedia/b2ee75fa-b1ef-4463-8b55-4b07c919383a/version1logo.png.aspx" height="80" width="100" /></td><td>
<a href="http://version1.com/">VERSION 1</a></td>
</tr>
<tr>
<td><img height="80" src="https://craftsmen.nl/wp-content/uploads/2016/02/logo.png" width="100" /></td><td>
<a href="https://craftsmen.nl/">Craftsmen</a></td>
<td><img src="http://www.majug.de/public/img/pivotal-logo.png" height="80" width="100" /></td><td>
<a href="https://pivotal.io/">Pivotal</a></td>
<td><img src="http://www.majug.de/public/img/liveperson.png" height="80" width="100" /></td><td>
<a href="https://www.liveperson.com/de">LivePerson</a></td>
<td><img src="http://www.majug.de/public/img/oio-logo.png" height="80" width="100" /></td><td>
<a href="https://www.oio.de/">Orientation-in-Objects</a></td>
</tr>
<tr>
<td><img src="http://www.majug.de/public/img/fluidops-logo.png" height="80" width="100" /></td><td>
<a href="https://www.fluidops.com/de/">fluidOps</a></td>
<td><img src="http://www.majug.de/public/img/andrena-logo.png" height="80" width="100" /></td><td>
<a href="https://www.andrena.de/">Andrena</a></td>
<td><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/JetBrains_Logo_2016.svg/440px-JetBrains_Logo_2016.svg.png" height="80" width="100" /></td><td>
<a href="https://www.jetbrains.com/">JetBrains</a></td>
</tr>
</tbody></table>
</div>
<br />
Please ask your company or group if they want to sponsor travel and accommodation for this tour.<br />
<p>
<b>Tour so far: Completed 50 out of 50 user groups</b>
<iframe height="480" src="https://www.google.com/maps/d/u/0/embed?mid=15Fxggg4LZeo8cvgbN5yTW8LsPhhMOsBB" width="640"></iframe>
<br />
<p><b>Tour schedule (updated May 15, 2018):</b></p>
<table border="0">
<tr align="center">
<th width="20"></th>
<th></th>
<th></th>
<th>Topic</th>
<th>Group</th>
<th>Travel sponsored by</th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>0</td>
<td><img src="https://secure.meetupstatic.com/photos/event/2/3/4/8/global_419049032.jpeg" width="100" height="75"></img></td>
<th>Jun 24, 2017</th>
<th>Twelve Ways to Make Code Suck Less + Reactive Programming</th>
<th><A href="https://www.meetup.com/Torun-JUG/events/240063320">Toruń JUG</A></th>
<th><A href="http://devoxx.pl/">DevoxxPL</A> and Toruń JUG, 4financeIT, Business Link Toruń, Kapala Grahic Design, Kona Coast Cafe, UCNTN, Allegro Tech</th>
</tr>
<tr align="left">
<td>1</td>
<td><img src="https://secure.meetupstatic.com/photos/event/d/6/2/c/global_4194828.jpeg" width="100" height="75"></img></td>
<th>Jul 17, 2017</th>
<th>From Functional to Reactive Programming</th>
<th><A href="https://www.meetup.com/csopensource/events/240645406/">Colorado Springs OSUG</A></th>
<th><A href="https://nofluffjuststuff.com">NFJS</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>2</td>
<td><img src="http://www.javamug.org/assets/custom/javamug-logo-transparent-bg-818bfe8c69d8912fa36587889804bc1c.png" width="100" height="75"></img></td>
<th>Aug 9, 2017</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="https://www.meetup.com/javamug/events/241961490/">Dallas Java MUG</A></th>
<th><A href="https://www.meetup.com/javamug">Dallas JUG</A></th>
</tr>
<tr align="left">
<td>3</td>
<td><img src="https://secure.meetupstatic.com/photos/event/3/3/1/a/global_271333082.jpeg" width="100" height="75"></img></td>
<th>Aug 10, 2017</th>
<th>Java 8 Programming Idioms</th>
<th><A href="https://www.meetup.com/GatewayJUG/events/241255725/">St. Louis JUG</A></th>
<th><A href="https://nofluffjuststuff.com">NFJS</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>4</td>
<td><img src="http://www.nimret.org/seajug/images/seajug_logo.png" width="100" height="75"></img></td>
<th>Aug 15, 2017</th>
<th>From Functional to Reactive Programming</th>
<th><A href="https://www.meetup.com/seajug/events/242132876/">Seattle JUG</A></th>
<th><A href="https://nofluffjuststuff.com">NFJS</A></th>
</tr>
<tr align="left">
<td>5</td>
<td><img src="https://secure.meetupstatic.com/photos/event/e/3/a/5/global_443278277.jpeg" width="100" height="75"></img></td>
<th>Aug 29, 2017</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="https://www.meetup.com/IllinoisJUGChicago/events/241723329/">Illinois JUG</A></th>
<th></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>6</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Aug 31, 2017</th>
<th>Design Patterns in the Light of Lambda Expressions</th>
<th><A href="https://www.meetup.com/Google-Developer-Group-Boulder/events/237938450/">Google Developer Group Boulder</A></th>
<th></th>
</tr>
<tr align="left">
<td>7</td>
<td><img src="https://pbs.twimg.com/profile_images/378800000373932680/00020995567cd2082e5e6a96bd232cb0_400x400.png" width="100" height="75"></img></td>
<th>Sep 10, 2017</th>
<th>Twelve Ways to Make Code Suck Less + Designing Functional Programs</th>
<th><A href="https://ti.to/tcube/dublin-java-user-group-september-2017">Dublin JUG</A></th>
<th>Dublin JUG, <A href="http://stackand.co/">Stack and .Co</A>, <A href="https://www.equifax.com">EQUIFAX</A>, <A href="http://www.guruteamirl.com/">GURUTEAM</A>, <A href="https://sonorplex.com/">SonorPlex</A>, <A href="https://tcubedublin.com">tcube</A>, <A href="http://version1.com">VERSION 1</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>8</td>
<td><img src="http://static.nljug.org/2bb62fc4a1/static/img/classic_logo.png" width="100" height="75"></img></td>
<th>Sep 11, 2017</th>
<th>Twelve Ways to Make Code Smell Less</th>
<th><A href="http://www.nljug.org/nieuws/nljug-university-sessie-met-venkat-subramaniam-powered-craftsmen-blue4it/">NL JUG</A></th>
<th>NL JUG, <A href="https://craftsmen.nl">Craftsmen</A>, <A href="http://www.blue4it.nl">blue4IT</A></th>
</tr>
<tr align="left">
<td>9</td>
<td><img src="https://pbs.twimg.com/profile_images/65814242/logo_2_400x400.png" width="100" height="75"></img></td>
<th>Sep 12, 2017</th>
<th>Twelve Ways to Make Code Suck Less + Exploring Java 9</th>
<th><A href="https://www.meetup.com/Enterprise-Java-User-Group-Austria/events/241997768/">eJUG Austria</A></th>
<th>eJUG</th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>10</td>
<td><img src="https://secure.meetupstatic.com/photos/event/4/7/2/e/global_178218222.jpeg" width="100" height="75"></img></td>
<th>Sep 13, 2017</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="https://www.meetup.com/Polish-Java-User-Group/events/243139820/">Polish JUG</A></th>
<th><A href="http://devconf.pl/">DevConf</A></th>
</tr>
<tr align="left">
<td>11</td>
<td><img src="https://secure.meetupstatic.com/photos/event/b/4/2/0/global_175786112.jpeg" width="100" height="75"></img></td>
<th>Sep 14, 2017</th>
<th>From Functional to Reactive Programming</th>
<th><A href="https://www.meetup.com/Warszawa-JUG/events/242850014/">Warsaw JUG</A></th>
<th><A href="http://devconf.pl/">DevConf</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>12</td>
<td><img src="http://www.agiledeveloper.com/images/silesiajug.jpg" width="100" height="75"></img></td>
<th>Sep 16, 2017</th>
<th>Functional, Java 9, Code quality</th>
<th><A href="https://www.meetup.com/Silesia-JUG/events/242282603/">Silesia JUG</A></th>
<th><A href="http://devconf.pl/">DevConf</A></th>
</tr>
<tr align="left">
<td>13</td>
<td><img src="https://virtualjug.com/wp-content/uploads/sites/2/2014/04/Vjug-small.png" width="100" height="75"></img></td>
<th>Sep 21, 2017</th>
<th>Parallel Streams</th>
<th><A href="https://virtualjug.com/the-power-and-perils-of-parallel-streams/">vJUG</A></th>
<th></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>14</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Sep 24, 2017</th>
<th>From Functional to Reactive Programming</th>
<th><A href="https://www.meetup.com/Jforum-Stockholm/events/242888021/">Stockholm JVM group and JForum</A></th>
<th><A href="http://www.umecon.se">Umecon</A></th>
</tr>
<tr align="left">
<td>15</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Sep 26, 2017</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="https://www.meetup.com/UmeJUG/events/242919621">Umeå JUG</A></th>
<th><A href="http://www.umecon.se">Umecon</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>16</td>
<td><img src="http://www.hjug.org/images/banner.gif" width="100" height="75"></img></td>
<th>Oct 7, 2017</th>
<th>Java 9 and Java 8 Idiosm Parallel Stream</th>
<th><A href="https://www.eventbrite.com/e/venkat-subrmaniams-you-pick-the-topics-jug-tour-houston-stop-tickets-37845999403#">Houston JUG</A></th>
<th></th>
</tr>
<tr align="left">
<td>17</td>
<td><img src="https://secure.meetupstatic.com/photos/event/5/7/b/8/global_455662456.jpeg" width="100" height="75"></img></td>
<th>Oct 16, 2017</th>
<th>Exploring Java 9</th>
<th><A href="https://www.meetup.com/javaBin/events/241336695/">Javabin Oslo</A></th>
<th><A href="http://ndctechtown.com/">NDC Conferences</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>18</td>
<td><img src="https://secure.meetupstatic.com/photos/event/c/6/0/4/global_297530692.jpeg" width="100" height="75"></img></td>
<th>Nov 6, 2017</th>
<th>Exploring Java 9</th>
<th><A href="https://www.meetup.com/fr-FR/preview/BruJUG/events/244257750">Brussels JUG</A></th>
<th><A href="http://devoxx.be/">Devoxx</A></th>
</tr>
<tr align="left">
<td>19</td>
<td><img src="http://vilnius-jug.lt/jug_vilnius-04-120.jpg" width="100" height="75"></img></td>
<th>Nov 11, 2017</th>
<th>Reactive Programming, Java 9</th>
<th><A href="http://vilniusjug62.eventbrite.com/">Vilnius JUG</A></th>
<th>Vilnius JUG</th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>20</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Nov 23, 2017</th>
<th>Java 8 Idioms</th>
<th><A href="https://keralajug.org/events/JDevCon2K17/">Kerela JUG</A></th>
<th><A href="http://www.saltmarch.com/">Saltmarch Media</A></th>
</tr>
<tr align="left">
<td>21</td>
<td><img src="https://secure.meetupstatic.com/photos/event/c/7/a/c/global_436671116.jpeg" width="100" height="75"></img></td>
<th>Nov 24, 2017</th>
<th>Functional & Reactive Programming</th>
<th><A href="https://www.meetup.com/jughyderabad/events/242987586/">Hyderabad JUG</A></th>
<th><A href="http://www.saltmarch.com/">Saltmarch Media</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>22</td>
<td><img src="https://secure.meetupstatic.com/photos/theme_head/d/c/7/2/full_7076434.jpeg" width="100" height="75"></img></td>
<th>Nov 25, 2017</th>
<th>Parallel Streams, Functional & Reactive Programming, Code quality</th>
<th><A href="https://www.meetup.com/MadrasJUG/events/241747956/">Madras JUG</A></th>
<th><A href="http://www.saltmarch.com/">Saltmarch Media</A></th>
</tr>
<tr align="left">
<td>23</td>
<td><img src="https://www.agiledeveloper.com/images/delhijug.png" width="100" height="75"></img></td>
<th>Nov 26, 2017</th>
<th>Functional & Reactive Programming, Code quality</th>
<th><A href="https://www.meetup.com/Delhi-NCR-JUG/events/242443501/">Delhi NCR JUG</A></th>
<th><A href="http://www.saltmarch.com/">Saltmarch Media</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>24</td>
<td><img src="https://secure.meetupstatic.com/photos/event/6/1/0/c/global_436704844.jpeg" width="100" height="75"></img></td>
<th>Dec 4, 2017</th>
<th>From Functional to Reactive</th>
<th><A href="https://www.meetup.com/Tampa-JUG/events/243676927/?eventId=243676927">Tampa JUG</A></th>
<th><A href="https://nofluffjuststuff.com">NFJS</A></th>
</tr>
<tr align="left">
<td>25</td>
<td><img src="https://secure.meetupstatic.com/photos/event/1/f/2/3/global_38107971.jpeg" width="100" height="75"></img></td>
<th>Dec 11, 2017</th>
<th>Exploring Java 9</th>
<th><A href="https://www.meetup.com/Miami-Java-User-Group/events/241669643/">Miami JVM Group</A></th>
<th><A href="https://nofluffjuststuff.com">NFJS</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>26</td>
<td><img src="https://secure.meetupstatic.com/photos/event/5/3/4/a/global_276381322.jpeg" width="100" height="75"></img></td>
<th>Dec 19, 2017</th>
<th>Java 9 & Fireside Chat</th>
<th><A href="https://www.meetup.com/atlantajug/events/244441378/">Atlanta JUG</A></th>
<th><A href="https://devnexus.com">DevNexus</A></th>
</tr>
<tr align="left">
<td>27</td>
<td><img src="https://secure.meetupstatic.com/photos/event/1/1/8/a/global_10324490.jpeg" width="100" height="75"></img></td>
<th>Dec 20, 2017</th>
<th>Refactoring to Functional Style</th>
<th><A href="https://www.meetup.com/sv-jug/events/241190567/">Silicon Valley JUG</A></th>
<th></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>28</td>
<td><img src="https://secure.meetupstatic.com/photos/event/c/4/c/e/global_71390382.jpeg" width="100" height="75"></img></td>
<th>Jan 10, 2018</th>
<th>From Functional to Reactive Programming</th>
<th><A href="https://www.meetup.com/DenverJavaUsersGroup/events/241101678/">Denver JUG</A></th>
<th><A href="https://nofluffjuststuff.com">NFJS</A></th>
</tr>
<tr align="left">
<td>29</td>
<td><img src="http://www.nejug.org/images/Logo_big_all.gif" width="100" height="75"></img></td>
<th>Jan 11, 2018</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="http://www.nejug.org/events/show/207">NE JUG</A></th>
<th><A href="https://nofluffjuststuff.com">NFJS</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>30</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Jan 12, 2018</th>
<th>From Functional to Reactive Programming</th>
<th><A href="http://www.montreal-jug.org/meetup/func-react/">Montreal JUG</A></th>
<th><A href="https://devnexus.com">DevNexus</A></th>
</tr>
<tr align="left">
<td>31</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Jan 22, 2018</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="https://www.jug.ch/html/events/2018/code_suck_less_lu.html">Luzern, Switzerland</A></th>
<th><A href="https://www.jug.ch/">JUG SWITZERLAND</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>32</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Jan 23, 2018</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="https://www.jug.ch/html/events/2018/code_suck_less_be.html">Bern, Switzerland</A></th>
<th><A href="https://www.jug.ch/">JUG SWITZERLAND</A></th>
</tr>
<tr align="left">
<td>33</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Jan 24, 2018</th>
<th>From Functional to Reactive Programming</th>
<th><A href="https://www.jug.ch/html/events/2018/reactive_programming.html">Basel, Switzerland</A></th>
<th><A href="https://www.jug.ch/">JUG SWITZERLAND</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>34</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Jan 25, 2018</th>
<th>The Power and Practicality of Immutability</th>
<th><A href="https://www.jug.ch/html/events/2018/immutability_sg.html">St. Gallen, Switzerland</A></th>
<th><A href="https://www.jug.ch/">JUG SWITZERLAND</A></th>
</tr>
<tr align="left">
<td>35</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Jan 26, 2018</th>
<th>The Power and Practicality of Immutability</th>
<th><A href="https://www.jug.ch/html/events/2018/immutability_zh.html">Zürich, Switzerland</A></th>
<th><A href="https://www.jug.ch/">JUG SWITZERLAND</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>36</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Jan 27, 2018</th>
<th>Java 9, Reactive, Parallel Streams, Code Quality</th>
<th><A href="http://www.majug.de/2018/01/27/agile-java-day/">Mannheim JUG</A></th>
<th><A href="http://www.majug.de/">Mannheim JUG</A></th>
</tr>
<tr align="left">
<td>37</td>
<td><img src="https://secure.meetupstatic.com/photos/event/5/d/e/global_189541502.jpeg" width="100" height="75"></img></td>
<th>Feb 28, 2018</th>
<th>The Power and Perils of Parallel Streams</th>
<th><A href="https://www.meetup.com/Detroit-Java-User-Group/events/247337217/">Detroit JUG</A></th>
<th>Detroit JUG</th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>38</td>
<td><img src="http://jugtorino.it/img/logo.jpg" width="100" height="75"></img></td>
<th>Mar 5, 2018</th>
<th>From Functional to Reactive Programming</th>
<th><A href="https://www.meetup.com/fr-FR/JUGTorino/events/241361441">Torino JUG</A></th>
<th><A href="https://voxxeddays.com/zurich/">VoxxedDay Zurich</A></th>
</tr>
<tr align="left">
<td>39</td>
<td><img src="http://www.jugmilano.it/images/logo/logo.png" width="100" height="75"></img></td>
<th>Mar 6, 2018</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="http://www.jugmilano.it/meeting-99.html">Milano JUG</A></th>
<th><A href="https://voxxeddays.com/zurich/">VoxxedDay Zurich</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>40</td>
<td><img src="https://secure.meetupstatic.com/photos/event/8/2/7/a/global_366333402.jpeg" width="100" height="75"></img></td>
<th>Mar 10, 2018</th>
<th>Multiple topics and FP Workshop</th>
<th><A href="https://www.meetup.com/eastcode-sessions/events/246638547/">košice</A></th>
<th>Eastcode Session</th>
</tr>
<tr align="left">
<td>41</td>
<td><img src="https://pbs.twimg.com/profile_images/724766332198211586/k7CoVOKP_400x400.jpg" width="100" height="75"></img></td>
<th>Mar 19, 2018</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="http://www.redlich.net/javasig/meetings/2018/mar2018.html">ACGNJ JUG</A></th>
<th><A href="https://nofluffjuststuff.com">NFJS</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>42</td>
<td><img src="https://secure.meetupstatic.com/photos/event/4/a/4/8/global_1819016.jpeg" width="100" height="75"></img></td>
<th>Mar 20, 2018</th>
<th>From Functional to Reactive Programming</th>
<th><A href="https://www.eventbrite.com/e/an-evening-w-venkat-subramaniam-from-functional-to-reactive-programming-tickets-43812896553">NYC JUG</A></th>
<th><A href="https://nofluffjuststuff.com">NFJS</A></th>
</tr>
<tr align="left">
<td>43</td>
<td><img src="https://secure.meetupstatic.com/photos/event/1/7/1/7/global_462785911.jpeg" width="100" height="75"></img></td>
<th>Mar 21, 2018</th>
<th>From Functional to Reactive Programming</th>
<th><A href="https://www.meetup.com/KansasCityJUG/events/241816242/">Kansas City JUG</A></th>
<th>Kansas City JUG</th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>44</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Apr 10, 2018</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="http://www.cojug.org/frontPage/2018-04-10-dinner-Twelve-Ways-to-Make-Code-Suck-Less-254/">Central Ohio JUG</A></th>
<th><A href="https://nofluffjuststuff.com">NFJS</A></th>
</tr>
<tr align="left">
<td>45</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Apr 11, 2018</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="https://www.meetup.com/cleveland-java/events/248439429/">Cleveland JUG</A></th>
<th><A href="https://nofluffjuststuff.com">NFJS</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>46</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>Apr 25 2018</th>
<th>Design Patterns in the Light of Lambdas</th>
<th><A href="https://www.meetup.com/BangaloreOpenJUG/events/248526846/">Bangalore JUG</A></th>
<th><A href="http://www.saltmarch.com/">Saltmarch Media</A></th>
</tr>
<tr align="left">
<td>47</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>May 08 2018</th>
<th>Java 9 and Java 10: The Key Parts</th>
<th><A href="https://www.meetup.com/Londonjavacommunity/events/249974999/">London JUG</A></th>
<th><A href="http://devoxx.be/">Devoxx</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>48</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>May 12, 2018</th>
<th>Functional to Reactive + Twelve Ways to Make Code Suck Less + Workshop</th>
<th><A href="https://www.meetup.com/Rome-Software-Discussion/events/249665040/">Rome SW Discussion & Code Garden Rome</A></th>
<th><A href="https://www.hotels.com">hotels.com</A></th>
</tr>
<tr align="left">
<td>49</td>
<td><img src="https://pbs.twimg.com/profile_images/1122140158/Juggy_version06_logo_400x400.png" width="100" height="75"></img></td>
<th>May 15, 2018</th>
<th>Functional + Reactive Programming</th>
<th><A href="https://www.parisjug.org/xwiki/wiki/oldversion/view/Meeting/20180515">Paris JUG</A></th>
<th>Paris JUG</th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>50</td>
<td><img src="http://ujug.org/wp-content/uploads/2015/06/ujug_flat_green_retina.png" width="100" height="75"></img></td>
<th>May 17, 2018</th>
<th>Do not walk away from Complexity, Run!</th>
<th><A href="http://ujug.org/event/venkat-subramaniam-2/">Utah JUG</A></th>
<th>Utah JUG</th>
</tr>
<tr align="left">
<td>51</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>May 24, 2018</th>
<th>Twelve Ways to Make Code Suck Less</th>
<th><A href="https://www.meetup.com/SVQJUG/events/248763895/">Sevilla JUG</A></th>
<th><A href="https://www.jetbrains.com/">JetBrains</A></th>
</tr>
<tr bgcolor="#E8E8E8" align="left">
<td>52</td>
<td><img src="https://agiledeveloper.com/images/mike.jpg" width="100" height="75"></img></td>
<th>May 28, 2018</th>
<th>Parallel Streams and CompletableFuture</th>
<th><A href="https://www.meetup.com/Java-Vienna/events/247519494/">Vienna JUG</A></th>
<th></th>
</tr>
</table>
<p>Hope to see you at a user group near you.</p>
</div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com20tag:blogger.com,1999:blog-3088609713768060708.post-65211410431334193022017-01-11T04:00:00.000-07:002017-01-11T05:43:08.797-07:00Closures don't Mean Mutability<div dir="ltr" style="text-align: left;" trbidi="on">
<p>In <A href="http://blog.agiledeveloper.com/2016/12/what-is-closure.html">a previous post we discussed how a closure differs from a lambda expression</A>. There's a misconception among some developers that closures are meant to promote mutability. That's not true and we will discuss the reasons why that thought is dangerous.</p>
<p>A closure <emph>closes-over</emph> its environment and binds to variables in its defining scope. But, that doesn't give it a birthright to mutate what's within its reach.</p>
<p>First, recollect that lambdas and closures are concepts from functional programming. Purely functional programming languages, like Haskell, for example, do not permit mutability. So, naturally, closures created in these languages will not be able to mutate. That in itself debunks the myth that closures are meant to mutate.</p>
<p>Today, languages that were traditionally imperative in style have bolted on the capability to program using the functional style. This includes languages like Java, C#, and C++. Languages like Ruby, Smalltalk, Scala, Groovy,... and the list goes on, have provided both imperative and functional style of programming since their beginning. Since these languages do not enforce immutability, it may lead us to believe that closures are mean to mutate, but we have to be extra careful about it—<A href="http://blog.agiledeveloper.com/2013/09/the-perils-of-mixing-paradigms.html">please see this link for some reasons</A>.</p>
<p>Some of the languages that support both imperative and functional style of programming are more protective than others when it comes to closures trying to mutate. Let's look at a few examples.</p>
<p>Here's an example in JavaScript.</p>
<pre style="background-color: #f0f0f0;"><code>let total = 0;
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
numbers.forEach(e => total += e);
console.log(total);
</code></pre>
<p><code>total</code> is a variable that has been initialized to the value <code>0</code>. Then, in the closure that is passed to the <code>forEach()</code> function we mutate that variable <code>total</code>, by adding each element's value from the array <code>numbers</code>. Let's save this code in a file named <code>sample.js</code> and run it, like so:</p>
<pre style="background-color: #f0f0f0;"><code>> node sample.js
55
>
</code></pre>
<p>The program produced the right output, but the closure did something morally wrong—it mutated a variable that it captured. This is unnecessary and totally avoidable as well. JavaScript does not stop us—<emph>programming in JavaScript is like exercising freedom of speech; it does not stop us from saying/doing stupid things—it leaves things to us to self govern.</emph></p>
<p>We will revisit this example to avoid mutability later in this post. Let's switch over to Java to recreate the same example.</p>
<pre style="background-color: #f0f0f0;"><code>import java.util.*;
class Sample {
public static void main(String[] args) {
int total = 0;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
numbers.forEach(e -> total += e);
//ERROR: local variables referenced from a lambda expression must be
//final or effectively final
System.out.println(total);
}
}
</code></pre>
<p>In this Java example, we create a local variable <code>total</code> in <code>main()</code> and mutate it within the closure. Java does not permit this. Java does not want us to mutate a captured local variable from within the closure.</p>
<p>Java is being protective in a good way and for a good reason. We will see why this is good real soon.</p>
<p>Unfortunately, Java protects us only from depending on any local mutable variable or changing any local variable. It does not extend this protection if we try to depend on or mutate an field in a class or if we mutate an object on the heap. Let's modify the previous code to bypass Java's protection—caution, not a very smart thing to do.</p>
<pre style="background-color: #f0f0f0;"><code>import java.util.*;
class Sample {
public static void main(String[] args) {
int[] total = new int[] { 0 }; //bad idea
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
numbers.forEach(e -> total[0] += e); //no ERROR, but don't do this.
System.out.println(total[0]);
}
}
</code></pre>
<p>We changed <code>int total = 0;</code> to <code>int[] total = new int[] { 0 };</code>. Instead of <code>total</code> being a local variable of type <code>int</code>, it became a local variable of type <code>int[]</code> where the actual value 0 now resides on the heap within the array. From within the closure, we're modifying the data within the <code>Array</code> instance that's on the heap. Java does not stop us, unfortunately. The result of this code will be <code>55</code>, but this code is destined to create trouble for us. For one, if desired, we can't make this code parallel—suppose the computation was time consuming or the size of the collection was large.</p>
<p>To prove why this is a bad idea, let's modify the code slightly.</p>
<pre style="background-color: #f0f0f0;"><code>import java.util.*;
class Sample {
public static void main(String[] args) {
int[] total = new int[] { 0 }; //bad idea
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
numbers.stream()
.forEach(e -> {
int temp = total[0];
try { Thread.sleep(100); } catch(Exception ex) {}
total[0] = temp + e;
}); //no ERROR, but don't do this.
System.out.println(total[0]);
}
}
</code></pre>
<p>In the code we iterate over the <code>numbers</code> collection using the <code>stream()</code> function. The closure is multiline—written so that we can see the mutability directly here in the closure, but better to call a function instead of writing multiple lines—that's <A href="http://blog.agiledeveloper.com/2015/06/lambdas-are-glue-code.html">a different, yet an important topic</A>. Even if we move the code that's within the closure into a separte method, this discussion applies to it as well.</p>
<p>In the closure, we get the first element of the array, store it into a temporary variable named <code>temp</code> and sleep for a fraction of a second—it's incredibly hard to show concurrency goof-ups in code in general, but this delay will make it easily evident. After the sleep, we update the first element of the array with the value of the element at hand.</p>
<p>Java once again does not stop us from compiling or executing this code. It produces the same correct result of <code>55</code> as the previous versions. However, this modified version will illustrate why the shared mutability within the closure is a terrible idea.</p>
<p>Let's make the code run in parallel. Change <code>numbers.stream()</code> to <code>numbers.parallelStream()</code>, like so:</p>
<pre style="background-color: #f0f0f0;"><code> numbers.parallelStream()
.forEach(e -> {
int temp = total[0];
try { Thread.sleep(100); } catch(Exception ex) {}
total[0] = temp + e;
}); //no ERROR, but don't do this.
</code></pre>
<p>Compile and run this version a few times. Isn't it fun that each run produces a totally different, unpredictable result.</p>
<p>The culprit here is the closure mutating a shared variable—one that it shares with other threads and the <code>main()</code> function.</p>
<p>While some languages prevent us from shooting ourselves in the foot, other languages sadly make it easy to blow up an entire village. Thankfully, all languages provide ways to avoid the mutability if we vigilantly choose to.</p>
<p>Let's revisit the JavaScript code to do the right things to compute the total of the values in that array.</p>
<pre style="background-color: #f0f0f0;"><code>let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const total = numbers.reduce((total, e) => total + e);
console.log(total);
</code></pre>
<p>The <code>reduce()</code> function avoided the mess with mutability and gave a direct way to perform the operation we desire.</p>
<p>Now, let's switch back to Java and make use of the <code>reduce()</code> function there as well:</p>
<pre style="background-color: #f0f0f0;"><code>import java.util.*;
class Sample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int total =
numbers.parallelStream()
.reduce(0, (sum, e) -> sum + e);
System.out.println(total);
}
}
</code></pre>
<p>We can run this code any number of times—put a slight delay within the lambda expression, if we like—the program will consistently produce the right result each time. The reason, we did not mess around with mutability.</p>
<p>We should avoid mutability in both lambdas and closures as much as possible. In purely functional languages we live under the offered protection. In the other languages, we have to be vigilant.</p>
</div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com5tag:blogger.com,1999:blog-3088609713768060708.post-51079401824264806122017-01-02T12:06:00.002-07:002017-01-02T13:13:44.031-07:00Tell me Now or Tell me When<a href="https://twitter.com/share" class="twitter-share-button" data-text="Tell me Now or Tell me When" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<p>There was no email when I was a kid or even when I was in college. Back in those days, if you wanted to communicate with someone, you wrote them a letter. Phone calls were not an option for a lot of reasons and in a lot of situations. Once you wrote them the letter, you mailed it. Then you waited.</p>
<p>Most of the time the mail reached them. Sometimes it got lost. And, yet, some times, they received only part of the mail. On occasions, I've received just envelopes, in another bigger envelope, with an apology letter from the postal service that the contents were lost—forever.</p>
<p>Today we live in the digital world. Times are different, right? True, but not entirely. That unpleasant <i>wait</i> seems to linger on.</p>
<p>On more than one occasion people from different parts of the world tell me: "You reply to email so promptly, wish others were that responsive." I don't think I do anything special, except to follow a simple rule:</p>
<p><center><i>Tell me now or tell me when.</i></center></p>
<p>Time is one of the most precious resources—mine and yours.</p>
<p>Generally I check emails two to three times a day. Early in the morning, soon after I wake up. Right in the middle of the day, around lunch—I am often at client sites, working with their teams, and don't have the ability to check or respond to emails while working. Then, I often check late in the evenings, either right after I get out of the client site or right after dinner.</p>
<p>Some emails require a short response. For example, my availability to speak at a conference or if I can teach a particular course. Other emails require a longer response. For instance, one may require multiple abstracts and another may require writing multiple examples to answer a technical question.</p>
<p>Generally I give myself thirty minutes to an hour each day for emails, split across the three time durations mentioned above. If I can respond to an email during that time, I simply do. If I can't give a meaningful response within 24 hours from the time the email was sent, then I send a short response stating when I will reply. Generally, such reply would say "Got your email. I will get back to you by June 5th regarding this," where June 5th may be a week or ten days from the response date. Then, immediately a task goes into my calendar to remind me a day or two before that deadline, to respond to that email.</p>
<p>I am not perfect. I fail at this, but thankfully only rarely—or so I like to believe. I have followed this simple rule of "tell me now or tell me when", well ever since I discovered email communication. I do that because time is very important—mine, and yours.</p>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com4tag:blogger.com,1999:blog-3088609713768060708.post-84432968830373271522016-12-30T06:17:00.000-07:002016-12-30T06:17:00.036-07:002016 Top Viewed Presentations @agileLearner<div dir="ltr" style="text-align: left;" trbidi="on">
<a class="twitter-share-button" data-size="large" data-text="2016 Top Viewed Presentations @agileLearner" href="https://twitter.com/share">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
The following were the five most viewed presentation on <a href="http://www.agilelearner.com/">http://www.agilelearner.com</a> in the year 2016:
<br />
<ul>
<li><a href="https://www.agilelearner.com/presentation/406">Builder Pattern</a></li>
<li><a href="https://www.agilelearner.com/presentation/367">Design by Contract vs. Design by Capability</a></li>
<li><a href="https://www.agilelearner.com/presentation/544">Java 8: Maps and Memoization</a></li>
<li><a href="https://www.agilelearner.com/presentation/413">Decorator Pattern</a></li>
<li><a href="https://www.agilelearner.com/presentation/2">Internal vs External Iterators</a></li>
</ul>
More videos coming in 2017.<br />
<br />
If you're not familiar with the site and like to get a taste of the presentations there, please check out the <a href="https://www.agilelearner.com/?q=free">free videos at this link</a>.</div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com1tag:blogger.com,1999:blog-3088609713768060708.post-42563211879182551832016-12-28T04:00:00.000-07:002017-01-11T05:39:23.687-07:00What is a Closure?<a class="twitter-share-button" data-size="large" data-text="What is a Closure?" href="https://twitter.com/share">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<p>We will first discuss lambda expressions and then see how closures are related.</p>
<p>Lambda expressions are anonymous functions which may receive parameters and may return a result. Functions that receive lambda expressions, create lambda expressions, and/or return lambda expressions are called higher-order functions. Lambda expressions are often passed as arguments to functions.</p>
<p>Let's take an example JavaScript function that reports the reader's current latitude position:</p>
<pre style="background-color: #f0f0f0;"><code>let reportLocation = function() {
navigator.geolocation.getCurrentPosition(
position => alert(position.coords.latitude),
error => alert('Sorry, could not get the location')
);
};
</code></pre>
<p>The <code>reportLocation()</code> function passes two anonymous functions or lambda expressions to the higher-order function <code>getCurrentPosition()</code>. <code>geolocation</code> is an asynchronous API, it will return immediately upon call and will eventually invoke one of the given lambda expressions with either the <code>position</code> or an <code>error</code>. You may try running the above code by clicking on the button <code>Report Location</code> (don't worry, your location will not be transmitted to anyone):</p>
<button onclick="reportLocation();">Report Location</button>
<script>
let reportLocation = function() {
navigator.geolocation.getCurrentPosition(
position => alert(position.coords.latitude),
error => alert('Sorry, could not get the location')
);
};
</script>
<p>Let's focus in on the first lambda expression:</p>
<pre style="background-color: #f0f0f0;"><code>position => alert(position.coords.latitude),
</code></pre>
<p>The lambda expression receives <code>position</code> as its parameter. The body of the function, besides calling a global function <code>alert()</code>, uses this parameter that is passed to it. It does not depend on anything else. This is the nature of a lambda expression—it only relies on its parameters.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-ikvOrK-AxiQ/WGMNeC1StyI/AAAAAAAAAXU/13mE9w-_hLkulhaw6CIYYbluzhHf59kiQCLcB/s1600/lambdaexpression.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="124" src="https://3.bp.blogspot.com/-ikvOrK-AxiQ/WGMNeC1StyI/AAAAAAAAAXU/13mE9w-_hLkulhaw6CIYYbluzhHf59kiQCLcB/s200/lambdaexpression.jpg" width="200" /></a></div>
<p>In the figure we see that the function <code>reportLocation()</code> created a lambda expression. That lambda expression floats away from <code>reportLocation()</code> and is held by the <code>getCurrentPosition()</code> to which it's passed as an argument. Eventually, long after the completion of the <code>reportLocation()</code> function, the lambda expression is called by the <code>getCurrentPosition()</code> function. The lambda expression survives its creator—this has consequences as we'll see soon.</p>
<p>The previous code reported the <code>latitude</code> using the <emph>infamous</emph> <code>alert()</code> function—that's nasty and we should not do such things. We should display the information on the page. How about displaying it in the following <code>div</code> tag:</p>
<h2><div id="display">...location will show up here...</div></h2>
<p>So, we want to invoke a function that will take the DOM element with <code>id</code> <code>display</cod> and call the <code>getCurrentPosition()</code> function. But, there is a catch. Let's see what that is with a slightly modified version of the <code>reportLocation()</code> function, we will call this <code>displayLocation()</code>.</p>
<pre style="background-color: #f0f0f0;"><code>let displayLocation = function(display) {
navigator.geolocation.getCurrentPosition(
position => ???,
error => alert('Sorry, could not get the location')
);
display.innerHTML = position.coords.latitude;
//This will not work, we don't have the position here.
};
</code></pre>
<p>The <code>displayLocation()</code> function receives a reference to the DOM element with <code>id</code> <code>display</code>. However, since the <code>getCurrentPosition()</code> function is asynchronous, we can't update the DOM element after the call—data is not available immediately after the call to <code>getCurrentPosition()</code> function.</p>
<p>The lambda expression we pass to <code>getCurrentPosition()</code> will live well past the call to the <code>displayLocation()</code> function. This lambda expression has to capture the <code>display</code> variable—the DOM element from its defining scope, this is called <emph>lexical scoping</emph>—and carry it over for use when the <code>position</code> is eventually passed to it by the <code>getCurrentPosition()</code> function.</p>
<p>A closure is a lambda expression that captures its surrounding environment. A closure carries state. While a lambda expression relies only on its parameters, a closure relies in addition on the state in its defining context—its lexical scope.</p>
<p>Let's rework the <code>displayLocation()</code> function and change the lambda expressions we passed earlier to <code>getCurrentPosition()</code> to closures:</p>
<pre style="background-color: #f0f0f0;"><code>let displayLocation = function(display) {
navigator.geolocation.getCurrentPosition(
position => display.innerHTML = position.coords.latitude,
error => display.innerHTML = 'Sorry, could not get the location'
);
};
</code></pre>
<p>Let's focus in on the first closure:</p>
<pre style="background-color: #f0f0f0;"><code>position => display.innerHTML = position.coords.latitude,
</code></pre>
<p>This closure, just like the lambda expression we saw earlier, receives a parameter named <code>position</code>. However, in its body, in addition to relying on the parameter <code>position</code>, it also uses the variable <code>display</code> that is not defined anywhere in the closure. The closure has captured this variable from it's defining scope.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-3wt-8eregBk/WGMNnQIYTFI/AAAAAAAAAXY/_nYC9uXrpK0jCMMddYkeNRXjqVFHPATYwCLcB/s1600/closure.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="138" src="https://4.bp.blogspot.com/-3wt-8eregBk/WGMNnQIYTFI/AAAAAAAAAXY/_nYC9uXrpK0jCMMddYkeNRXjqVFHPATYwCLcB/s200/closure.jpg" width="200" /></a></div>
<p>The figure shows that the <code>displayLocation()</code> function creates a lambda expression, but unlike the ones created by the <code>reportLocation()</code> function, this lambda expression captures the <code>display</code> variable. Even though the <code>displayLocation()</code> function finishes, the reference it receives as parameter lives well past that time, held within the lambda expression.</p>
<p>We can now call this method in the <code>onclick</code> event of a button, like so,</p>
<code>displayLocation(document.getElementById('display'));</code>.
<p>Here's the button to display the location in the DOM element we defined earlier. You may click on the button and observe that the <code>div</code> element we created earlier eventually changes to display the <code>latitude</code> of your position.</p>
<button onclick="displayLocation(document.getElementById('display'));">Display Location</button>
<script>
let displayLocation = function(display) {
navigator.geolocation.getCurrentPosition(
position => display.innerHTML = position.coords.latitude,
error => display.innerHTML = 'Sorry, could not get the location'
);
};
</script>
<p>Lambda expressions are stateless, they rely only on their parameters. Closures are lambda expressions that carry state; they capture their environment, they <emph>close-over</emph> their defining context and can bind to variables in their lexical scope.</p>
<p>We saw examples above in JavaScript. Here's an example of a lambda expression in Java:</p>
<pre style="background-color: #f0f0f0;"><code>import java.util.*;
class Sample {
public static void main(String[] args) {
Arrays.asList(1, 2, 3)
.stream()
.map(e -> e * 2)
.forEach(System.out::println);
}
}
</code></pre>
<p>In this example the <code>map()</code> function receives a lambda expression—the body of this function relies on its parameter and a literal. No external dependencies.</p>
<p>On the other hand, the following code uses a closure:</p>
<pre style="background-color: #f0f0f0;"><code>import java.util.*;
class Sample {
public static void main(String[] args) {
int factor = 2;
Arrays.asList(1, 2, 3)
.stream()
.map(e -> e * factor)
.forEach(System.out::println);
}
}
</code></pre>
<p>The <code>map()</code> function in this example receives a closure—it has closed-over it's environment and captured the variable <code>factor</code> from its lexical scope.</p>
<p>In short, lambdas are stateless. Closures close-over their environment, carry state, and capture variables in their lexical scope.</p>
<p>Capturing impure state can be trouble some. Please refer to the series of blogs starting from
<a href="http://blog.agiledeveloper.com/2015/12/what-are-pure-functions.html">What are Pure Functions?</a> for discussion about the consequences of impurity.</p>
<p>Also see <A href="http://blog.agiledeveloper.com/2017/01/closures-dont-mean-mutability.html">Closure don't Mean Mutable</A>.</p>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com0tag:blogger.com,1999:blog-3088609713768060708.post-66903192013279624732016-08-17T04:00:00.000-06:002016-08-17T05:58:43.589-06:00Lesson on Agile Learner: JavaScript Programming Idioms<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="https://twitter.com/share" class="twitter-share-button" data-text="Agile Learner: Lesson on JavaScript Programming Idioms" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script><p>
The Lesson on <a href="https://www.agilelearner.com/lesson/1295">JavaScript Programming Idioms</a> is a series of example driven presentations that show how to create fluent code in JavaScript.
<p>
The lessons are available to subscribers only. If you're new to the site, please take a look at <a href="https://www.agilelearner.com/?q=free">these videos that are freely downloadable</a>.
<br />
Interested in subscribing? Check with your company or organization to see if they would purchase a yearly subscription for you (and your colleagues too).<br />
</div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com1tag:blogger.com,1999:blog-3088609713768060708.post-20471074769808184302016-07-07T07:00:00.000-06:002017-01-14T17:56:19.857-07:00Thoughts through Tweets<style media="screen" type="text/css">
div#thoughtsThruTweets p:nth-of-type(even) {
background-color: #FOFOFO;
}
div#thoughtsThruTweets p:nth-of-type(odd) {
background-color: #C8C8C8;
}
</style>
<a href="https://twitter.com/share" class="twitter-share-button" data-text="Thoughts in tweets by @venkat_s" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<h5><I>This is a collection of <A href="https://twitter.com/venkat_s">some thoughts expressed by Venkat Subramaniam over tweets...</A></I></h5>
<div id="thoughtsThruTweets">
<p>Using profanity doesn't make us expressive, it simply shows we're vulgar and lacking.</p>
<p>I think, history will say, Scala & Clojure are to FP as C++ is to OOP.</p>
<p>"safety" in type safety is as comforting as "security" in social security.</p>
<p>Design patterns are the cliches of software design.</p>
<p>I've found intuition and gut feeling to be the most useful tools for design so far.</p>
<p>I don't want my project stakeholders to be guests on my projects, I want them to have a "skin in the game," investing their time & effort.</p>
<p>Learning a lib, a lang is easy. To improve code & change development style is hard-requires discipline & great self awareness.</p>
<p>"My boss is not convinced" is euphemism for "I'm not convinced, but I'm in denial (& it feels good to blame it on the boss)."</p>
<p>Relying heavily on some of our key strengths sometimes tends to be our major weakness.</p>
<p>I prefer a healthy dose of skepticism over naive optimism or incessant pessimism.</p>
<p>As engineers, we're good at telling boss what won't work. We should learn to explain what'd work & how it'll help the business.</p>
<p>Jumping into Scrum without practices to promote sustainable dev is like jumping into marriage with no real commitments.</p>
<p>There's usually a point in time when a project can be turned to success, but that opportune moment is rarely at the end.</p>
<p>Each time someone hears the words "best practice" God kills a few neurons.</p>
<p>You know you work for an enterprise when you dial long distance to schedule guy in the next room to fix your projector.</p>
<p>If work is not "having fun" you're likely holding on to a stinking job than being in pursuit of a passionate profession.</p>
<p>When getting into TDD, be prepared not to learn, but to unlearn; the more experience writing code, the more unlearning there is.</p>
<p>Architecture for a product is like salt for a meal–essential, must be in right proportion, & can't be self-serving.</p>
<p>Shaving head, losing shirt, walking barefoot doesn't make us Gandhi; at best only a cheap imitation of a 1/2 naked fakir.</p>
<p>A professional who doesn't learn to fail, fails to learn.</p>
<p>Given a choice between code that's simply sensible vs. hypothetically extensible, I prefer the former any day.</p>
<p>Let's be driven by inspiration, and not desperation, to attain that success that we can relish.</p>
<p>The words static and synchronized are menace to TDD.</p>
<p>Be opinionated, but unbiased. "The man who never alters his opinion is like standing water, and breeds reptiles of the mind" William Blake.</p>
<p>Continuing to use miserable developer tool is like being complacent in an abusive relationship-why not get out for a better life?</p>
<p>They say "end does not justify the means." But, in agile development, do we expect means that justify the end?</p>
<p>"We learn more by looking for the answer to a question and not finding it than we do from learning the answer itself." Lloyd Alexander</p>
<p>The irony of our industry, we brave to automate the world, yet we fear automating our projects.</p>
<p>IMHO, a great talk/book has both high information density & velocity; how much quality info is given & its pace.</p>
<p>If your company wants you to follow only standard practices, they're asking you to follow the path to mediocracy.</p>
<p>Dear company, owning code your programmers can't understand is worst than losing the code.</p>
<p>Zinnser: "Easy writing makes hard reading; hard writing makes easy reading" Not just writing, it's apt for coding.</p>
<p>If your code is not testable, it simply means your design sucks.</p>
<p>Ignorance is a tumor, remove early.</p>
<p>The only little predictable aspect of our lives is its unpredictability.</p>
<p>"It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle.</p>
<p>In Java, you work for the compiler; in Scala the compiler works for you.</p>
<p>Trying to release product fast by compromising quality is like trying to lose weight fast by smoking.</p>
<p>"Methods to gain wisdom: by reflection (noblest), by imitation (easiest), and by experience (bitterest)"—source unknown.</p>
<p>What's the difference between a mafia and the government? Mafia doesn't require you to do paper work for the money they take away from you.</p>
<p>Dear developer, pride not developing complex software; strive instead to develop a capable and useful software.</p>
<p>Two sets of people scare me: those who can't follow instructions and those who can only follow instructions.</p>
<p>A good programmer should never fear throwing away code.</p>
<p>A framework that's your darling today is the one you'll hate in two years (make that four if you're a fanboy).</p>
<p>Some people teach me how to live; others how not to. I learn from both. Thankfully, however, each day I get to meet more of the former.</p>
<p>My mentors did not change the word, but hey they changed my world. Be a mentor.</p>
<p>You can't be Agile if your code sucks</p>
<p>If you think a piece of code is unusable, design for reuse to remove all doubt.</p>
<p>Complain to the one who can fix, praise to the one who can benefit.</p>
<p>It's not a mistake that the design has to change, it's a mistake not to make it feasible and cost effective to evolve (within reason).</p>
<p>"Yes" is nice to hear, "No" not so much, but "Yes" followed by inaction is the most difficult to deal with.</p>
<p>Decades ago I wrote bad code without knowing, today there's no doubt anymore, what a difference :)</p>
<p>If programmers are like (aspiring) musicians, some create music, others merely noise.</p>
<p>Stuff we create deserves checkin, not when it's perfect, but so we can evolve it fearlessly.</p>
<p>Checkins also serve as a form of information radiator.</p>
<p>What surprises me the most is not the realization I was wrong, but the strength of the conviction I had before that.</p>
<p>It's funny that most of us think the world has to change, but rarely think twice about ways to change ourselves.</p>
<p>Learning's like peeling the onion, you have to go through layers, & it involves tears...of frustration and then of joy.</p>
<p>Sometimes the hardest part of solving a problem is realizing and accepting the simple solution that's been there in front of you all along!</p>
<p>Depth of knowledge + ability to communicate + with a touch of humor + engaging the audience == a great presentation</p>
<p>If there's one thing we can learn, it's that we can't achieve desired results, leave alone perfection, in one try; results evolve.</p>
<p>hope is contagious</p>
<p>Success comes not from agreement, but from alignment.</p>
<p>There are no good people and bad people, three are only good behaviors and bad behaviors through the eyes of a context.</p>
<p>A key design skill we need to develop is the ability to discern accidental complexity from inherent complexity.</p>
<p>Theory is to programmers as vegetables are to children, essential but you can't just feed them bland.</p>
<p>Why do companies waste time asking questions in interview? Ask candidates to do real work, that's what you're hiring for.</p>
<p>A great business touches many pockets, a great person touches many hearts.</p>
<p>Passion is necessary but not sufficient; passion in the absence of hard work is like a seed with no soil.</p>
<p>Knowledge is a wealth that grows as you give.</p>
<p>If all we care about is speed, be prepared to end up fast in the ditch. Agile's about both speed & direction or relevance.</p>
<p>When problem solving, half the solution, an essential skill, is to eliminate unnecessary details.</p>
<p>I love it when someone, instead of complaining, takes time to research & sends a solution to problem. Lots of respect for folks like this.</p>
<p>The only constant is that Heraclitus quote about the only constant.</p>
<p>I admire the human quest to create new powerful devices, so fellow humans have options like never before to play solitaire.</p>
<p>Every moment, every interaction is an opportunity to learn, some teach us what we could be, other what not to be.</p>
<p>Greater the ignorance, larger seems to be the conviction.</p>
<p>Languages we learn should fundamentally change the way we think, challenge, shake the roots we've come to believe & rely upon.</p>
<p>Seems to be nothing more fulfilling & motivating than writing a todo list on a piece of paper & striking items off as they're completed.</p>
<p>The effort is not in writing, it's really in rewriting.</p>
<p>Rather than searching for agile practices to follow, pick a problem worth fixing & look for ways to realize that.</p>
<p>I find it helpful to understand the economic reasons for actions and the economic impact of the change.</p>
<p>TDD is a skill, it involves a decent amount of unlearning, relearning, and reevaluation. Let's not expect to get good at it instantly.</p>
<p>Sure TDD requires discipline, its a way of thinking, and all that, but I feel programmers need a sense of awareness to benefit from it.</p>
<p>The rigor in development must be in proportion to the cost and consequences of failure.</p>
<p>Languages are like vehicles, they all help us get around, some better than others. Travel on a few, based on the needs.</p>
<p>Curiosity - it's the pathway from good to great.</p>
<p>Everyone's complaining about someone, so collectively we all suck. Now that we got that figured, can we do something useful?</p>
<p>It's perfectly safe, no one has ever died of an extra act of kindness.</p>
<p>How others acts is not in our control, but how we react is entirely; We have the right of way on the civil parkway.</p>
<p>Quietness is a state of mind that can be experienced even in a noisy environment.</p>
<p>Most humans seem to be much better at critiquing than creating. We can channel this wisely thru feedbacks for a greater good.</p>
<p>It's much more fun to laugh with people than to laugh at them.</p>
<p>Does anyone keep track of their MTBYS - Mean Time Between Yak Shaving .</p>
<p>Conflicts & war arises, not due to respect for one's belief, religion, group, gender, or sect, but from the lack of it for the others.</p>
<p>My marriage has matured to the level that my wife and I can now fluently communicate... using airport codes.</p>
<p>Number one rule of collective ownership, we should never get into merge hell... we should only give it... with frequent check ins.</p>
<p>Those feeling strong that an organization must change, seriously start & follow the answers to question "how can I change."</p>
<p>Kicking ourselves often out of our comfort zones is a safe way to broaden that zone.</p>
<p>No matter where we reside, lets avoid living in the state of denial.</p>
<p>A better measure of audience or colleagues is not the answers they give, but the questions they ask.</p>
<p>A great leader, rather than instructing, motivates people to realize their organization's goals.</p>
<p>The first step in effecting change is to give it a fighting chance, most people seems to be convinced system's too rooted to change.</p>
<p>Each of us is living a dream, we just have to check often that it's ours and still ours.</p>
<p>Can't pause the passage of time, but every moment's an opportunity to turn growing old into a fruitful act of growing up</p>
<p>Sure there're so many things we can't change, but let's improve things_ however small_that's glaring at us and we 'can' change.</p>
<p>Good habits don't come from simply talking about them, but honed by sincere, disciplined, continuous, and deliberate practice.</p>
<p>Each day seems to be a realization of this inequality: Know < things forgotten << ignorant</p>
<p>a functional language in the hands of a dysfunctional team is like my junk in the hands of the TSA-it's not solving the real problem.</p>
<p>It's really not about what we learn, but how we learn it. So much of what we know builds and feeds on each other.</p>
<p>Failure is the stepping stone of success, but look up frequently to ensure the stones lead us in the right path & not in circles.</p>
<p>Speaking and writing, like any activity, gets better once we begin to enjoy it.</p>
<p>Use of the word "they" in the same sentence as "build" or "test" is a sign the team needs to improve the ways.</p>
<p>So much code being developed "design by accident" rather than "design with intent."</p>
<p>Agile in the absence of disciple and commitment is like marriage in the absence of love and trust - not sustainable.</p>
<p>We all want to create simple design, but the act of creating such a design is not that simple.</p>
<p>The mindset I prefer is to have a mind that's not set in ways. </p>
<p>You know it's time to stop and get back to important stuff when you hear yourself say "aren't these yaks cute."</p>
<p>Experience is not the passage of time but a measure of how our efforts have critically altered the ways we think and act.</p>
<p>Each generation faces atrocities of madmen & their group of thugs, only to prove that kindness & courage of the common hardworking prevails.</p>
<p>For a programmer, a day without a yak to shave is like a day without sunshine.</p>
<p>Some are too eager to teach lessons, not realizing, the student for lessons is not someone else, but the deserving inner self.</p>
<p>When will the software industry realize that the only true measure of estimates is in units of yak shavings.</p>
<p>I admire the innate resilience of programmers, without it the first set of compiler errors would have put an end to the field.</p>
<p>It's been discovered the darkest place in the world is located in the state of denial.</p>
<p>An important skill for programmers to develop is their sense for code and design smells, especially in their own code.</p>
<p>Best practices are like pills, targeted prescription with expiration date. Not wise to swallow them, ignoring the label.</p>
<p>learn to practice, practice to learn.</p>
<p>Everyone has three ages: the calendar age, the how-I-feel age, and how-others-feel based on the maturity they display.</p>
<p>writing is throwing the ingredients together, rewriting is seeing it turn into a sauce.</p>
<p>There are no good people and bad people, only developed minds and developing minds.</p>
<p>The weak put up with bureaucratic nonsense, the brave fight it, the wise simply work around it, never taking eyes of the goals to realize.</p>
<p>Having observed multiple enterprises I've come to realize that "stage-gate" is where their process and productivity goes to die.</p>
<p>you are the stories you tell.</p>
<p>A sense of prolonged professional comfort is a sign of setting into complacence.</p>
<p>The more I interact with organizations, the more I realize how important competent people are to the core of their success.</p>
<p>It's not much of a charm, but emotional stability and willingness to make things work, are essential qualities for customer-interacting jobs.</p>
<p>The most difficult to learn aren't the ones that add to our knowledge, but those that demand changes to our habits and behaviors.</p>
<p>convention over configuration is awesome when we know and can remember the conventions.</p>
<p>Reboot seems to be a proven solution, not just for windows, but from treadmills to airplanes!</p>
<p>it's interesting to meet organizations where management wants devs. to create quality code, but devs feel their management won't let them.</p>
<p>We looked at this problem and said we can solve it using a pool of threads. Now we have a pool of problems.</p>
<p>I really hate being distracted from my distractions.</p>
<p>It's quite clear how poor my design abilities were 10 years ago. What's not clear is how it sucks today, what I'll tell 10 years from now.</p>
<p>Weak can turn strong with diligence while the strong may turn weak from complacency.</p>
<p>Our field has fundamentally transformed in the last two decades, from devs fighting DLL hell to fighting assembly and jar hell.</p>
<p>It's quite dangerous when the experts quit listening and insists on the world accepting their dogmas and prescriptions.</p>
<p>Those who can't spend time and effort on automated feedbacks have to expend a greater magnitude on the aftermath.</p>
<p>If they hear you say "change" they ask you "Why?" If they see you succeed, they ask you "How?"</p>
<p>Have scientist figured this phenomenon that slows time to a crawl when you get on the treadmill?</p>
<p>You know it's time to take a break when you're fixated to review and fix code printed on the back of someone's T-shirt.</p>
<p>Good communication skill is not just having a nice fluency of words but must be accompanied by fervorous good attitude.</p>
<p>Software development is not an act of spewing code but a balanced art and economics of evolving and refactoring just enough code.</p>
<p>I fear my children becoming programmers one day, and start to ask questions, and discover my dark past—coding with COM and CORBA.</p>
<p>It appears, most of the "we can't convince our management" comments come from those who've not taken the time/effort to convince themselves.</p>
<p>Code smell is a wonderful metaphor (coined by @KentBeck); the more we put up with bad smell, the sooner we impair our senses to recognize.</p>
<p>The first step in paying technical debt is to check if we're actively acquiring avoidable new debt each day.</p>
<p>Professionalism is an act where we openly compliment and critique our ideas in a civil manner and end the day with a cheerful handshake.</p>
<p>There's cure for ignorance, and even incompetency, but all is lost in the presence of complacency.</p>
<p>A good learning should not merely fill our brains with more knowledge, but influence a change in our behavior, so we can achieve more.</p>
<p>A perfect way to fail is to be bent on making things perfect instead of valuable.</p>
<p>The biggest challenge is not the availability of tools or techniques, but the strong resistance to explore, experiment, & adapt.</p>
<p>It's critical to know if a low cost service is a result of higher efficiency or lower quality.</p>
<p>Son: "Dad can I have it?" Me: "302" Son (to my wife): "Mom?" Wife: "404"</p>
<p>So many of us confuse listening with agreeing, but they both are quite orthogonal.</p>
<p>There are but two constants, the first, as Heraclitus said, is change, and the second is the inborn human resistance to it.</p>
<p>One of the biggest services a mentor can provide is help people quickly get out of their comfort zone.</p>
<p>I am, but a work in progress, being debugged and evolved every day of my life, with a few bugs in me fixed, and a few new ones added.</p>
<p>Automated test is an act of self discipline where we're willing to invest time now for a greater saving later. Reaping that benefit today.</p>
<p>I think it takes some courage to invest in ourself.</p>
<p>Worry not if the American dream is dying, instead wake up to realize your dreams.</p>
<p>Asking someone to comment poorly written code is like asking them to take a higher interest loan to play their current debt.</p>
<p>Create fast should not imply drop quality, but to focus on the most essential features and business value.</p>
<p>Why do people speed like crazy on the roads and stand still on escalators?</p>
<p>Passion is the alarm that wakes you up, so you can go realize your dreams.</p>
<p>Let's give variables the names they deserve.</p>
<p>Expect a good mentor to serve as a ladder than as an escalator or an elevator/lift.</p>
<p>Each of us have two personalities, one before we have our first caffeinated drink of the day, and a gentler one after.</p>
<p>Let's judge code, not people.</p>
<p>There's often a tradeoff between more vs. better of something.</p>
<p>Ruby: 'Hey dude, we're about the same age :snicker' ~ Java: "eh, you're as cool as you think?{grunt}" ~ Lisp: (damn juveniles)</p>
<p>The problem with those of us who strive for perfection may be we believe we're perfect in defining perfection.</p>
<p>It's not the syntax or the idioms that we should pickup first in programming, but a sense for code smells.</p>
<p>My estimations skills are only surpassed by my ability to produce bug free software.</p>
<p>Giving in to the fear of failure is the biggest of all failures.</p>
<p>10% of the time, we write ugly code for performance reasons, the other 90% of the time, we write ugly code to be consistent.</p>
<p>Software is never written, it's only evolved.</p>
<p>If we ever figure a way to time travel, I will go back and stop that dude who put space in the directory name "Program Files"</p>
<p>Exercising is hard, but it makes the rest of the day so much easy.</p>
<p>The most important investment we make each day is on ourself, for if we don't trust, how silly to expect others to.</p>
<p>The irony of software dev_a field where most practitioners claim things change real fast, and, yet vehemently resist that very change.</p>
<p>Martin Luther King effected change, not by yelling America sucks, but by telling the dreams he had for her better future.</p>
<p>Oh, the pattern name you're looking for is "coding in desperation."</p>
<p>So many of us are eager to find an answer, but without knowing the question.</p>
<p>Instead of hearing "we're agile!" I'd like to hear "we're successful and here's why."</p>
<p>A programmer's command of the computers is in proportion to how often, and how comfortable, they're on the command line.</p>
<p>An expert is shaped, not by all the answers they've learned, but by the questions they've not been embarrassed to ask.</p>
<p>My days would be so much better if I don't have to constantly deal with… myself.</p>
<p>In programming, the variable flag is pronounced "smell."</p>
<p>The problem with most of us is not the one of misconception, but the one of conviction, that what have it all figured out.</p>
<p>Jealousy's a feeling we don't wanna work hard to attain what others have. Inspiration motivates us to attain & exceed. Cultivate the latter.</p>
<p>change is easy when we change often.</p>
<p>I like meeting someone negative and snobbish from time to time, they remind me, and make me thankful, how wonderful rest of the world is.</p>
<p>Let's not confuse experience & comfortable. One requires constantly getting out of the comfort zone, the other settles in.</p>
<p>programmers should care about warning as they care about errors.</p>
<p>Flying worldwide has given me insights on how reservation systems handle concurrency. It's called "yell out the passenger's seat number."</p>
<p>Ego is like cholesterol---there are good parts and bad parts.</p>
<p>The word to define the behavior of postponing to the last minute is not agile. It's called unorganized, lack of discipline.</p>
<p>Education is not a pursuit of a degree but the elevation and broadening of ones mind.</p>
<p>In programming, exceptions have become anything but. </p>
<p>I don't mind people talking to me when I'm working, as long as they don't expect me to actually listen. :)</p>
<p>I realize I can never convince anyone. At the best, I can merely lay down good reasons to help others convince themselves.</p>
<p>More advices are given than taken.</p>
<p>We may get better results if, rather than appraising employees' performance, managers focus on nurturing a good team culture.</p>
<p>It's an irony that fields where rapid feedback's hard are longing while the field where it's largely affordable's wants all up front.</p>
<p>You've shown what great things a simple man with discipline and perseverance can truly achieve. You live in our memories. #Mandela</p>
<p>Few things are satisfying as literally seeing tears of joy fill the eyes of someone, at the moment of their hard earned success.</p>
<p>There's no excuse worst than the one we give to ourself.</p>
<p>Quality of a presentation = inspiration * information</p>
<p>One of the easiest way to reduced quality of any activity is to cram it all on or near the due date.</p>
<p>We have no way to influence the state of the world we enter, but, I hope, we can do something good about it before we exit.</p>
<p>It's better to be an exceptional you than an average imitation of someone else you consider exceptional.</p>
<p>I don't take new year resolutions, I prefer more frequent, everyday resolutions. It's lot easier and fun to fail each day than once a year.</p>
<p>On any given day, I meet two sets of people: those living to die and those dying to live. The latter is so much fun to hang around with.</p>
<p>Every design, I bet, looked like a good idea at that time, however long ago and short lived that time period was.</p>
<p>Any seemingly good set of practices may yield better results when used contextually instead of prescriptively.</p>
<p>Experience is the passage through time where we gain the ability to look at our own past and say "what the heck was I thinking then?"</p>
<p>I hear that TDD is mainstream, most organizations follow Threat Driven Development.</p>
<p>In the digital age, developing the skills to ask the right questions is more important than having the right answers.</p>
<p>Success is a garland of small failures tied together with a thread of perseverance.</p>
<p>Teaching is not only about helping students acquire knowledge, but help them pick up better learning skills and work habits.</p>
<p>It's unintelligent to repeat the mistakes of yesterday. Get creative, go make new ones for today.</p>
<p>Trust is like hard earned wealth, we have to work each day to build it and use caution not to lose it all in one foolish act.</p>
<p>I think that authors who write more than one book suffer from short term memory. Why else would they take on the pain yet again? :)</p>
<p>What's being spoken is often not what's being heard.</p>
<p>It's not about fixing a bug, but learning how things actually work.</p>
<p>A good mission in life is not to rush to perform what others do, but fill the gaps in a passionate area where others won't.</p>
<p>The hardest step in solving any problem seems to be asking for help.</p>
<p>Functional programming is cool, but the real charm is in what it makes easy—lazy evaluation.</p>
<p>A design lesson I've learned over the years: behavior over state.</p>
<p>Most of us have to fix just one thing - attitude - rest of it gets fixed fairly easily.</p>
<p>When coding, null should be pronounced smell.</p>
<p>I really like TV... turned off.</p>
<p>agility is about delivering value early without compromising a reasonable quality of the product or the heath of the developers.</p>
<p>I don't prepare for talks, the talks prepare me—there's so much learning that happens.</p>
<p>Strive to be an informed constructive critique and a contributor, not a troll.</p>
<p>Know thy audience.</p>
<p>The best gift I've received from anyone is the warmth of their company and the lasting memory of good times with them.</p>
<p>Sorry, you have to wait, I will get to complaining about your flaws as soon as I fix mine.</p>
<p>Never deprive people the pleasure of enlightenment through discovery.</p>
<p>At some point we've to realize that effecting change in an organization start with us overcoming our own fears.</p>
<p>Efficiency is attained not by doing tasks better or faster, but by avoiding those that shouldn't be done in the first place.</p>
<p>always fun when in a room with two people, one telling the code is terse while the other pointing it's verbose.</p>
<p>There are only two options: adapt or perish. The first one's really fun once we break the inertia.</p>
<p>Complain as much as possible, but armed with facts, not with prejudice.</p>
<p>Let IDEs minimize typing not remove thinking.</p>
<p>Being content with available language/lib capabilities is as dangerous as being ignorant of them, given how nascent our field really is.</p>
<p>Every day is an opportunity to refactor our minds.</p>
<p>A good code should read like a story, not like a puzzle.</p>
<p>History bestowed us with Lincoln, Gandhi, MLK, Theresa, Mandela,... wish the world was truly blessed so these heroes were not needed.</p>
<p>what if we quit coding and start expressing?</p>
<p>The most rewarding, yet the hardest, part of writing seems to be the willingness to remove words to strengthen the sentences.</p>
<p>Values are not what we teach about, but the ones we live by.</p>
<p>It's not the failures that leads to success but the perseverance to apply the lessons learned.</p>
<p>A maintainable code is a gift we give ourselves for the future.</p>
<p>Most of what we reject is not due to the lack of viability of an idea, but one of fear from unfamiliarity with it.</p>
<p>Lesson this morning: Sometimes if it seems hard it may not need an added thrust but an extra thought.</p>
<p>The first human who turned noise into music is the true genius.</p>
<p>If there's is a lesson life has thought me, it's that there's no single way to ever look at anything.</p>
<p>Education shouldn't be an attempt to fill heads with knowledge, but an act of maturing minds to continuously learn & adapt.</p>
<p>Let's not compromise quality in favor of quantity.</p>
<p>I'm honored to have great students who teach me well.</p>
<p>If it's getting hard to effect change, chances are the organization may be stifled by a big circle of finger pointing.</p>
<p>It's quite ironic, but anything (tool, API, library,...) with the word 'simple' in its name rarely is.</p>
<p>You won't pick dentist based on their "money back guarantee." Don't pick a vendor based on strong SLA, but on reputation & relationship.</p>
<p>You doing the right things today is a good way to earn a sincere 'thanks' from the future you.</p>
<p>It's amazing how technology has evolved. We've gone from calling the wrong person to texting the wrong person.</p>
<p>You don't need anyone's permission to be professional.</p>
<p>When that urge to comment strikes, see how to express that thought in code instead of comment.</p>
<p>People often are not as convinced about things as they think they are.</p>
<p>If only we could compare the cost of quality with the cost of not having it...</p>
<p>Poor quality is like crime, there will always be someone willing to commit it. But, we can hope & nurture, so more of us have better values.</p>
<p>Speed without discipline is the fastest way to wreckage.</p>
<p>Tools or techniques used blindly do not create good design, programmers being conscious, making good decisions, applying right tools, do.</p>
<p>Some organizations try to breed programmers in captivity; they can't survive outside of their frameworks or IDEs.</p>
<p>Treating someone nice is not an act of respect but of self-respect.</p>
<p>Most programmers seems to be bothered by syntax; get past that soon, the real scare is in the semantics.</p>
<p>There are two kinds of people we run into each day: those we work with and those we work around.</p>
<p>indirection is the ultimate sophistication in programming.</p>
<p>The four uses of frameworks: reuse, confuse, misuse, and overuse.</p>
<p>Somewhere in the transition from childhood to adulthood, quite a few humans go from "I don't know" to "I don't care to know."</p>
<p>A sentence with "I don't like..." should not end in period, but continue to suggest why and offer some constructive alternatives.</p>
<p>I know for certain that the rest of my day can only be better, for I am starting by writing a regular expression.</p>
<p>It's little things that make a big difference in the hearts.</p>
<p>Geeks complaining about technology is far more pleasant to hear than folks complaining about people.</p>
<p>The lessons from history are filled with wonders, from what the heck was wrong with people, to awe about small group's heresies & tenacity.</p>
<p>After traveling thru much of this world I've discovered there are only four major religions: cricket, soccer, football, and hockey.</p>
<p>After roaming several parts of this world I conclude there's actually a universal form of expression. It's called graffiti.</p>
<p>Confusion may arise in the presence of complexity but it also appears in the case of unfamiliarity.</p>
<p>I've taken a few decades to acquire great wealth that's in the form of friendship with some beautiful minds.</p>
<p>Coding in dream is fun.</p>
<p>We are but victims of poor designs.</p>
<p>The net effect of complexities and ceremonies is multiplicative, not additive.</p>
<p>A true appreciation/understanding of a language emerges when we dig into its semantics, not just its syntax</p>
<p>We can't make legacy code better by writing more of the same way; it needs change in behavior and practice.</p>
<p>The biggest impediment to learning is the reluctance to interact. Good work cultures break such barriers, making it safe to communicate.</p>
<p>When I was young, I was told there's heaven and hell. As I got older, I learned that to be true and both coexist here on earth.</p>
<p>When learning new constructs I wish more developers ask "how do we test it" instead of asking "how do we debug this"?</p>
<p>aspiration without perspiration --> unfulfilled dreams.</p>
<p>Often questions seem more interesting than answers.</p>
<p>t seems like writing the introduction is the hardest part of writing a book. Coming up with a good subtitle, the second hardest.</p>
<p>automated tests are but one of many means to an end—rapid useful feedback. If there are better easier ways in a context, go for it.</p>
<p>Until we've fully immersed in both an exceptionally static typed & a superb dynamic typed lang, we have no rights for opinions on typing.</p>
<p>what makes both writing and coding so interesting and challenging, at the same time, is there's simply no one way to express.</p>
<p>sometimes it takes years to realize how suckish some practices are.</p>
<p>When did presentation get attached to slides instead of communication?</p>
<p>If employees are reluctant to express their view, and discuss issues, an organization has a bigger problem to tackle first.</p>
<p>Better feedback comes, not from demos, but active use of an application while being developed.</p>
<p>It's important to learn from mistakes quickly, so we can move on to make new ones.</p>
<p>Writing code is a lot of fun, but throwing out code is pure bliss.</p>
<p>I'm shocked that they'd actually number a flight 404, don't complain if no geeks board.</p>
<p>When selecting a language, library, or a framework, it's vital to evaluate the ability to automate tests at various levels.</p>
<p>A field improves, not from corporate mandates, but when its practitioners grow up to act professionally.</p>
<p>Nothing exposes ones ignorance of a topic than an attempt to teach it.</p>
<p>Java came late to the party, but they brought great desserts</p>
<p>Life's too short to be complaining about things we can't also help improve.</p>
<p>I really like the sense of humor my friends have. They endorsed me on Linkedin for XML.</p>
<p>I like going to foreign lands so I can learn first hand how ridiculously I've been pronouncing their town names.</p>
<p>A poor performing unreadable code is hard to cure on both fronts.</p>
<p>What a teacher teaches is far less important that what a student learns and how it's applied.</p>
<p>There's humor in life, wherever we look.</p>
<p>Let not the current employment restrict professional and personal interest, growth, and freedom of expression outside of work.</p>
<p>Don't turn your problems into your customers' problems.</p>
<p>The true pleasures of meeting someone is hearing their stories of life and their perspectives.</p>
<p>Every day is bright, as I find someone random, who's better than me in some way, and quietly helps me improve myself.</p>
<p>Both in coding and writing, experience takes us from the anxious state of trying to figure out "what to write" to "what to remove."</p>
<p>Frequent travelers are never in jet lag, they're only in denial.</p>
<p>A programmer though "I could solve this problem using a monad," now has a sequence of problems.</p>
<p>When we focus on what we don't really need, it takes away time, money, effort, and focus from where it's really needed.</p>
<p>When we compromise quality for speed, we end up losing both.</p>
<p>I feel like all my code is like Benjamin Button, from the way it's created to how it turns with each refactoring.</p>
<p>By nature we're wired to mistake familiar as simple and the unfamiliar as complex.</p>
<p>A bright day will come when software developers treat errors as normal instead of as exceptions.</p>
<p>Nothing helps make things fall in place better than an approaching deadline.</p>
<p>I call on restaurants to reduce serving size. You will help reduce waste and waist.</p>
<p>"temp" is the name of a variable that's crying for its dignity and recognition.</p>
<p>There comes a point in time when it's more prudent to deprecate a language than deprecating some of it's features.</p>
<p>Experience is developing the courage to realize we were wrong so many time over the years.</p>
<p>I've come to realize the struggle to write automated tests come from lack of understanding & poor design than lack of tools.</p>
<p>Poor quality code is a reflection of lack of respect we carry for what we do, often with out realizing it.</p>
<p>self-realization is the best realization.</p>
<p>The easiest way to learn a new language quickly is to keep learning new languages. It raises our bar so unfamiliar turn to similarities.</p>
<p>What we say is a reflection of the subject, how we say it is a reflection of us.</p>
<p>Life, love, and time - can't think of anything more precious than that.</p>
<p>I have a feeling that each task I strike off on my todo list gives birth to a few more tasks.</p>
<p>A good code invites the reader.</p>
<p>If we're in a course, conference, or a workshop and we stare at our own monitors, that's called being at the wrong place at the wrong time.</p>
<p>It's hard to effect change when the key participants do not truly understand its impacts and benefits.</p>
<p>A good professional places quality over quantity.</p>
<p>It's through struggles and failures that real learning happens.</p>
<p>The hardest things to explain are the ones we've not understood well.</p>
<p>Mind, the tricks you play!</p>
<p>Family: A small group sent to planet earth to be brutally honest about you.</p>
<p>Nothing brings comforting smile out of a C++ programmer as an unhealthy dose of type coercion.</p>
<p>A sense of urgency should help us create relevant things with better quality, not lot of things with poor quality.</p>
<p>when nothing else works…. reboot</p>
<p>No timeboxed activity that improves our learning and influences steps forward can be a waste of time. It's a necessary investment.</p>
<p>When I hear someone say "hi baby" I wonder if the subject is addressed that way for possible cuteness or probable behavior.</p>
<p>Three levels of programming competency: "it's all magic" -> "here's how it works" -> "here's how it should work"</p>
<p>Programming with locks is not concurrent programming, it should be called congestion programming.</p>
<p>Concise vs terse: short enough, transparent, easy to read -vs- short, opaque, hard to understand. Let's favor concise, not terse code.</p>
<p>Ah, caught myself creating a Rube Goldberg machine, thankfully sanity kicked in.</p>
<p>Perseverance is not the determination to stick with the current plan of action but the will to adapt so we can reach our goals.</p>
<p>I'd rather hear a "no" than a "yes" followed by inaction.</p>
<p>It's not just about speed, agility is also about heading in the right direction.</p>
<p>If we mostly follow what the masses do, we will mostly get only the results that everyone gets.</p>
<p>When young, we figure out it's a struggle to change the world, but as we get older we realize the real struggle is in changing ourselves.</p>
<p>Test code now or detest it later.</p>
<p>big change, big fail</p>
<p>make it work, then make it better real soon.</p>
<p>Let the tools make us productive but not ignorant.</p>
<p>Love them bugs that teach a lesson and set me straight.</p>
<p>Weigh in the potential productivity gain from an external dependency with the probable cost to maintain it along.</p>
<p>Exercising is a practice that turns from aversion to addiction.</p>
<p>In a world that seems to honor complexity & clutter, shredding the shame of simplicity is the first step to creating better design.</p>
<p>Feedback empowers those willing to listen.</p>
<p>Some organizations practice what I'd like to call "agile by convenience."</p>
<p>We're victims of our own complexities.</p>
<p>Writing gets better, with each writing, and each review.</p>
<p>A good design is not the one that correctly predicts the future, it's one that makes adapting to the future affordable.</p>
<p>After traveling to many parts of the world, I've discovered there is one common language. It's called giggles.</p>
<p>big wins are built from small successes.</p>
<p>Career is like a vehicle you operate, not hard to get it moving, but you still have to start, accelerate, steer, and decide where to go.</p>
<p>That desire, to solve problems without understanding them.</p>
<p>Q: "What to do if our designers create detailed design, insist we code it?" A: Start by confiscating their cassette players & floppy disks.</p>
<p>Comments that tell us what the code means is not a form of documentation but a cry for refactoring.</p>
<p>The more time-sensitive or mission critical a project is the shorter should be the feedback loop.</p>
<p>Experience does not teach us to write different code, it teaches us to write it differently.</p>
<p>Life's easier if, instead of the attitude of drivers, we've the agility of bicyclists who get around blocks than being stuck complaining.</p>
<p>Our field has turned good ideas of OOP into unnecessary pollution & excessive mutation of state. Often don't need as many object nor state.</p>
<p>Coming from the OO background, I feel that lazy evaluation is the polymorphism of FP, equally exciting and all the more powerful.</p>
<p>Rewrote a piece of code three times in flight. Now that I closed the laptop, a much better implementation comes to mind!</p>
<p>A well written code deals with failure. A poorly written code is a failure.</p>
<p>The true value's not in the different, but in the difference; not in how different you are, but in how you make a difference.</p>
<p>Anyone who thinks they have a sense of humor has never tried to be funny around their teenagers.</p>
<p>I don't really give tech talks, I simply drag my able body to the podium, then the languages and tools take over to do the rest.</p>
<p>I have a feeling that the current times will be referred to, not too distant in the future, as the stagecoach days of programming.</p>
<p>It's that feeling all over again, when the answers are waiting for you to ask the right questions.</p>
<p>If there's just one thing programming has taught me, it's the value of perseverance.</p>
<p>Most projects would be dead if there were no deadlines.</p>
<p>We all suck when we start something new. The easiest way to address that—suck soon, suck often.</p>
<p>Running a code to prove its thread-safe is like proving that someone is not guilty by asking them if they are.</p>
<p>Refactoring is not only about transforming code, it's equally about how it transforms the coder.</p>
<p>The difficulty to solve a problem increases with our level of stress.</p>
<p>Easy to write is important, but not more than easy to test and to maintain.</p>
<p>Learning good practices can help turn teams 180 degrees, but they have to practice to avoid turning another 180 degrees.</p>
<p>We can't fix punctuality issues by starting late. Everyone has reasons for their delays. Value and respect those who show up on time.</p>
<p>The best moments, however short, are when an adult reveals the child in them.</p>
<p>I know of only one way to write readable code—ask a colleague to read it.</p>
<p>Learn for school, you're a student. Learn for a living, you're a professional. But learn to share & enlighten, you become a great teacher.</p>
<p>Talent is a gift that comes wrapped in hard work.</p>
<p>With Java 8 we don't do any thing different than before, but we do it differently, for the better.</p>
<p>Don't let other's behavior define your character.</p>
<p>If you mostly talk to me negative about others in their absence, I've to assume you do the same about me in my absence.</p>
<p>Professionals don't compete to show who's better; they collaborate to make the world around them better for everyone.</p>
<p>Exercise does the mind good, it's effect on the body is a bonus.</p>
<p>Programmer: one who can name their children quite easily but has a hard time naming their variables.</p>
<p>learning is empowering.</p>
<p>Coding beats any other form of inflight entertainment, hands down.</p>
<p>Being a programmer is like a kid in a candy store, every single day.</p>
<p>Clear head and dirty shoes; the effect of getting out into nature. </p>
<p>When a test fails the programmer succeeds in learning a bit more.</p>
<p>A smile is worth a thousand words.</p>
<p>Things are often not as complex as we make them to be.</p>
<p>we often perform poorly when trying to anticipate and identify performance problems.</p>
<p>Sentences with 'always', 'never', and/or 'only' are most often wrong.</p>
<p>Don't let programmers watch movies w hacking. While the audience go "how cool," the geek's like "eh, wrong options, missed a -r. sigh."</p>
<p>Code quality is the professional responsibility of the technically savvy—the onus is not on who lacks the knowledge, details, or skills.</p>
<p>It's OK to create unmaintainable code, that's if you work with people you hate.</p>
<p>If you don't test the software you create someone else will, with a negative impact on both cost and reputation.</p>
<p>Lambda expressions should be glue code. Two lines may be too many.</p>
<p>People don't fear failure. They fear being seen as a failure.</p>
<p>documenting is so much easier than self-documenting, but not as effective.</p>
<p>No need to carry along that bag of hate through the journey of life, travel light, especially if you like to reach some heights.</p>
<p>Learning is a process by which a curious mind transforms a set of unknowns to knowns in a way that it exposes an abyss of unknowns.</p>
<p>Developers are often taught to write code, but not how to write code.</p>
<p>Think more, type less. Aim for minimalism, fewer states, less mutability, and just enough code for the known, relevant parts of the problem.</p>
<p>Functional is declarative, but declarative is not necessarily functional.</p>
<p>It's the struggles that make us stronger.</p>
<p>Typed "code is composable" and got autocorrected to compostable; love it when autocorrect knows about the state and quality of my code.</p>
<p>"I've set the wedding date. I've not asked her out yet."---how software projects are managed.</p>
<p>Whatever it is the you want to do, put your heart and soul into it. Not because it deserves better, it's because you do.</p>
<p>Software field has evolved. Decades ago some programmers wrote bad code. Now they most copy and paste it.</p>
<p>A passive teacher focuses on teaching the students. An active teacher focuses on learning with the students.</p>
<p>The quality of code is inversely proportional to the effort it takes to understand it.</p>
<p>The toughest part of testing JavaScript is shaking the belief that it is impossible or unmanageably hard.</p>
<p>If current dir path has space in its name, Karma does not auto run tests on file change. Proves that space in file names is bad karma.</p>
<p>The main problem with most products is not their capability, but one of imposed complexity beyond reasonable need.</p>
<p>desire improvement than perfection.</p>
<p>True freedom can be cherished when what a human can do, out of their own good will, isn't judged and restricted by the biases of another.</p>
<p>Eating is good, eating a lot in one sitting, not so much. Same with coding.</p>
<p>Best time to change what we do is when things are going well. Let go of what's working, with confidence, to reach for a greater good.</p>
<p>Get very uncomfortable when things begin to feel quite comfortable.</p>
<p>A very pleasing moment is when I hear good things about people I know, especially friends, from total strangers.</p>
<p>If you're right, you learned it well. If you're wrong, you're learning it now. Either way you come out winning.</p>
<p>Both in life and in writing, would be nice to favor more discussions and fewer bullets.</p>
<p>Programmers: A group of people who create puzzles, they call code, for each other to solve.</p>
<p>Just realized that typing the word "intimidating" is in itself intimidating.</p>
<p>It is so much fun to start something and see it quickly take shape in ways never imagined. A humbling experience.</p>
<p>Some of our weaknesses, when cautiously channelled, can turn into a strength.</p>
<p>put the effort to get the result.</p>
<p>There is so much we can give, each one of us, way more than we realize or will.</p>
<p>Much like how quality of code varies, quality of automated tests vary too. Don't assume all is well if tests are being written.</p>
<p>What's separable is more easily testable. That's another reason cohesion and modularity matter.</p>
<p>significant whitespace is a feature some languages provide as a way to mess with developers' sanity.</p>
<p>Don't measure someones capability based on your ability.</p>
<p>Time's wasted when we argue and correct every fool that comes along. Wise to focus on helping those who genuinely desire to improve.</p>
<p>Quick fixes may appear as short cuts in the near term but we end up cutting short in the long run.</p>
<p>Programming is an act of rewriting our assumptions.</p>
<p>The sad part of middle age is watching the people you looked up to when young fade away into history.</p>
<p>Either lead or follow, don't stay put.</p>
<p>"What do I want to improve today?" is a great thought to start the day.</p>
<p>Good habits and practices, like success, is not for everyone.</p>
<p>Software development: a profession where people get paid to write poor quality code and get paid more later to cleanup the mess.</p>
<p>Those who can't design are condemned to document. </p>
<p>Automation is easier if we aspire to automate, but equally loathe manual efforts.</p>
<p>Happiness: moment when what you enjoy meets what you do.</p>
<p>Software development involves both innovation and productization. Our practices need to facilitate both.</p>
<p>Never cease an opportunity to influence a young mind.</p>
<p>We seem to be driven largely by the fear of short term gains than the pleasure of long term wins.</p>
<p>There seems to be nothing so greatly motivating than a fast approaching deadline.</p>
<p>There are good times and then there are interesting times.</p>
<p>Development mindset in the last few decades has been CRUD. It seems to be shifting to streams… we're at the cusp of newer abstractions.</p>
<p>The ease of testing a function is inversely proportional to the number of levels of abstraction it deals with.</p>
<p>The first step in becoming a better programmer is to let go of the conviction that we can code it once and get it right on the first write.</p>
<p>The answers are all around us, waiting for us to simply pop the questions right.</p>
<p>Willingness to adapt and deal with the situation on hand is not agile, it's called attitude.</p>
<p>I dare software products to change their "Accept the Terms and Conditions" to "tl;dr"</p>
<p>There's one student I really care to teach everyday, it's the one within. The fact others learn along is a nice side-effect.</p>
<p>I'm shocked. I accidentally looked up & saw a man, walking with head straight up, facing forward, with no device on hand, like it's 2005.</p>
<p>The best way to kill a great idea is to ask for the permissions to implement it.</p>
<p>Forget cholesterol levels, doctors have found a new measure of people's health. It's called CPM or complains per minute?</p>
<p>Look but take time to see, hear but be keen to listen, touch but the heart, speak but as wise, and laugh but not at others.</p>
<p>The more we taken on the less we're able to deliver and the quality suffers too. Manage time & task wisely.</p>
<p>Quick to judge, slow to understand - we can do better than that.</p>
<p>A better person is not the one with fewer faults, but one who finds fewer faults in others.</p>
<p>We can't call our times modern, no way, while humans constantly provoke & fight each other rather than joining hands for a better world.</p>
<p>quick or quality—choose one.</p>
<p>Design is problem solving. Solving one problem often exposes other problems. Need desire, perseverance, and focus to forge ahead.</p>
<p>Good music does the mind good.</p>
<p>Those who sacrifice quality to get performance may end up getting neither.</p>
<p>Funny we complain software's not extensible, yet we're comfortable dining in restaurants that can't deviate the slightest from their menus.</p>
<p>The biggest impediment to FP is lack of familiarity. Code with that style in anger and it begins to get easier in no time.</p>
<p>fp != cryptic code — languages should promote meaningful syntax, programmers should choose sensible parameter names.</p>
<p>When will humans learn, imposing your ideology, however great you may perceive it to be, on others is a terrible act.</p>
<p>Everyone's emotional, but we express it differently. It's that difference that makes life enjoyable.</p>
<p>When our own money and personal reputation is involved in what we create, we think differently.</p>
<p>Automated testing slows us down when we code, speeds us up when we refactor.</p>
<p>We should take as much care about how we present as to what we present.</p>
<p>Don't bother testing software, if it does not work your users will tweet about it.</p>
<p>Software development is no longer a game of hobbyists. It affects humans in many ways. High time we improve our practices and discipline.</p>
<p>Open and timely communication is a reflection of mutual respect.</p>
<p>Nature has wired us to thrive on feedback, right from our first moments. Make active use of it in every form possible.</p>
<p>I hated Haskell's static typing until I realized it infers the type and I don't really have to mess with that detail for most part.</p>
<p>No success ever emerged from staying comfortable.</p>
<p>Lack of professional discipline is an sign of occupational stupidity.</p>
<p>Of all the journeys, the one from confusion to clarity is the most enjoyable.</p>
<p>Writing is addictive.</p>
<p>Programming is a wonderful act of continuous discoveries.</p>
<p>Writing is like the morning fog, rewriting is like the Sunshine that follows.</p>
<p>Writing does not consume time, it consumes you.</p>
<p>Improving oneself each day is the most enlightening part of living.</p>
<p>The toughest part of writing is mustering courage to delete an entire chapter and start over. The best part is the result.</p>
<p>Success is important. But, an organization's desire to succeed at all cost, by sacrificing their employees' living, is morally wrong.</p>
<p>After all it really takes PHD to succeed, no not a degree, but Perseverance, Hard work & Determination.</p>
<p>After all it really takes PHD to succeed, no not a degree, but Perseverance, Hard work & Determination.</p>
<p>JavaScript is like an infant. It's cute to play with, but you have no clue why when it begins to cry.</p>
<p>The reason we call something a common curtesy is to remind ourselves that it's common and expected.</p>
<p>Automate the heck out of the world around you.</p>
<p>It's not about how long, but how much practice one has had.</p>
<p>resolve(n): the state of mind to leave a box of donuts untouched.</p>
<p>Two words that make children happy and, at the same time, make parents sad: “snow day”</p>
<p>Write, rewrite, and again, until no words can be removed to convey the meaning.</p>
<p>Remember, there's always a human at the other end.</p>
<p>With almost anything in life: what matters is not what we have, but what we do with it</p>
<p>I've had one hell of a programming career. From DLL hell to Jar hell through assembly hell down to the npm hell. What's next?</p>
<p>Three things for a programmer to exercise daily: mind, body, and code.</p>
<p>Nothing seems more profound than David Wheeler's words "All problems in computer science can be solved by another level of indirection.”</p>
<p>A vigilant programmer should design to manage inherent complexities but work hard to remove accidental complexities.</p>
<p>I suspect when programmers have trouble sleeping they don't count sheep. They're busy deciding if it should be an int, long, BigInteger,...</p>
<p>TIL that some developers do Test Dreaming Development.</p>
<p>To love someone we must be first willing to accept them instead of changing them.</p>
<p>Deliver excellence, not excuses.</p>
<p>Cruelest person in the history: inventor of the alarm.</p>
<p>Mostly all we leave behind are memories. Let's make them good.</p>
<p>So often we work hard to find correct solutions to the wrong problems, without ever realizing it.</p>
<p>It's often not easy to make things easy.</p>
<p>Thinking of friends, though their smartness grabbed my attention at first it's their humbleness & kindness that locked in the friendship.</p>
<p>I have a strong suspicion that the autocorrect feature was designed to ruin relationships.</p>
<p>agile is not about finishing fast. It’s about sensibly adapting based on the realities as they emerge.</p>
<p>There is a circus that comes to stage every four years in the US. This time around it picked up more clowns than usual.</p>
<p>Messing with state is the root of many problems, both in software and in politics.</p>
<p>An enriching experience is not the amount of time or the number of years, but the amount of absorption and realization.</p>
<p>Refracturing: "the act of refactoring code without any tests or quick feedback loops."</p>
<p>Have we created a culture that our colleagues are so reluctant to ask for help?</p>
<p>Of all my wants, what I ask myself each day is for more patience and humility.</p>
<p>May be I'm old school, but I'm used to hearing words like "could you please?" and "thank you" in questions and conversations.</p>
<p>Realizing ones own weaknesses is the greatest strength one could have.</p>
<p>Coding for work, brings money. Coding for community, brings satisfaction. Coding something up the family wants, now that's true bliss.</p>
<p>mixing mutability with lambdas/closures is dysfunctional programming.</p>
<p>The trainings we're given teach how to write code, a lot of it. The coaching we really need is how to write a lot less with better quality.</p>
<p>Can't improve our coding style without explicitly observing & making efforts to change our coding habits. Habits & style == cause & effect.</p>
<p>Perseverance is one of the most important virtues of a programmer.</p>
<p>Minutes turn into hours, hours into days, days into months, and those into years. Let not turn "I have a dream" to "I once had a dream."</p>
<p>Hearing there is only one approach or way is not a sign of wisdom but a poor reflection of zeal.</p>
<p>A good code makes us feel less stupid.</p>
<p>Help, not hinder.</p>
<p>Sometimes have to step close to a problem to see the solution. But then, sometimes farther away. The challenge's in deciding which is right.</p>
<p>Every experience is a learning experience.</p>
<p>So many of us take so many things for granted. Need more empathy.</p>
<p>To teach someone what you know you have to start from what they know.</p>
<p>Knowledge, wealth, and happiness: they are ephemeral and, at any time, there's always someone out there with more of each that we do.</p>
<p>There's nothing more satisfying than hearing one’s friends being praised.</p>
<p>A great day starts with a set of unknowns and ends with a new pile of unknowns.</p>
<p>separation of concern is everyones concern.</p>
<p>Mother's love is special. It's just love at first, turns into tough love when needed, and eventually becomes unconditional love.</p>
<p>The more one codes well with one particular language the less they bode well with yet another language.</p>
<p>It does not matter how awesome and slick a piece of code looks, it's not good if it's hard to test.</p>
<p>If you wanna nail it be willing to first fail it, several times.</p>
<p>We're too eager to teach programming to kids, but let's not lose sight of teaching the critical problem solving skills.</p>
<p>There is no better time to get better.</p>
<p>Learning's a lot like mountain hiking. It's up hill, exhausting, we lose the way at times, but the view from the summit makes it all worth.</p>
<p>If being a startup means writing unmaintainable code, many organizations are in startup mode even decades later.</p>
<p>The issue is not one of lack of principles or values, but of insistence that everyone should have the same.</p>
<p>Relationships are reflections of attitudes.</p>
<p>No developer should be expected or required to defend the use of any technology, library, or framework that helps deliver value.</p>
<p>Technology infatuation is as bad as tech stagnation. Decisions have to be for the right reasons, not because it's the next cool thing.</p>
<p>If your app/org stores password in an easily decryptable to human readable form, exercise 1 of 2 options: please fix it or blow the whistle.</p>
<p>Family(n): Individuals huddled under one roof, each staring intently at their own devices.</p>
<p>It does not matter what one does. What matters is that they enjoy it, it results in good, and they work hard to do it super well.</p>
<p>Weeks to get response to some emails? I suspect some servers may be printing & delivering to destination servers using the postal dept.</p>
<p>Nothing wrong in waiting for opportunity to knock, but when it does one still has to get up to respond timely.</p>
<p>The most fundamental respect for someone should arise from the fact that they are a fellow human, everything else is secondary.</p>
<p>It's not our capability to plan meticulously that matters but it’s our ability and willingness to change and adapt.</p>
<p>Technical decisions should have expiration dates, at the turn of which should be reassessed.</p>
<p>Desire improvement, not just change.</p>
<p>Creating unmaintainable code is a crime against humanity.</p>
<p>Level of test automation is a strategic decision, not a tactical one.</p>
<p>Writing expressive code is a massage for the mind.</p>
<p>Say something, someone’s hurt by words. Be quiet, the silence irks some. No win situation. Focus on intentions & actions rather than words.</p>
<p>Learning is a proof that you're better than the person you saw in the mirror yesterday.</p>
<p>The joy of hearing a child sing rarely comes from the music.</p>
<p>My children have concluded that the only thing in my house that gets older than me are my jokes.</p>
<p>Each of us has been given a gift. The challenge is for us to figure out what that is, then go out and put that to darn good use.</p>
<p>You're but the stories you tell.</p>
<p>Both writers & readers partake in readability. Writer through quality; reader by their familiarity to the context & the programming style.</p>
<p>For each thing we desire more, the less we may get of something else. Ask for the most relevant and be mindful of tradeoffs.</p>
<p>Don't retain the incompetent and unmotivated. They don't deliver, plus it deprives someone else more capable and deserving.</p>
<p>Value getting work done over meaningless bureaucratic compliance.</p>
<p>It's as important, if not more, to develop the skills to ask the right questions as amassing knowledge to give the right answers.</p>
<p>For every form you're forced to file an untended yak dies someplace.</p>
<p>The only substitute for hard work is lost opportunities.</p>
<p>Mutability needs company, it often hangs around with bugs.</p>
<p>The opposite of success in not failure; it's the lack of perseverance.</p>
<p>I suppose the best part of traveling is actually coming back home.</p>
<p>A developed nation sets a great example for the rest, it does not tears itself apart. Let's behave developed. We need to help, not hate.</p>
<p>A broken build may be a sign of active development. Don't dread breaking the build and please don't leave it broken.</p>
<p>Blessed are the ones who can do more of what they want to do and a lot less of what they have to do.</p>
<p>It's darn easy to preach but damn hard to practice. Be wise, only preach what you truly practice.</p>
<p>Each home needs more children, a lot more, for, each day, the adults need a large search party, to find their misplaced pairs of glasses.</p>
<p>Maturity is when you take more interest in your future and wellbeing than others do.</p>
<p>Working software ain't good enough, let's create relevant working software.</p>
<p>Design or despair.</p>
<p>Efforts to make everyone happy has 0% success rate.</p>
<p>Every interaction that involves an open mind & willingness to listen becomes a remarkable learning experience no matter the expertise level.</p>
<p>consider rapid (cost effective) maintenance and not just rapid/fast coding.</p>
<p>Valuable lesson I've learned for better living: test databases are like toothbrush, not a good idea to share, keep them personal/local.</p>
<p>Don't expect others to invest in you more than you're willing to in yourself.</p>
<p>Nothing else may come close to pleasing a programmer as a well working automation.</p>
<p>Great power in the hands of someone lacking discipline is a recipe for disaster.</p>
<p>Programming with dependencies is like organizing an event with the in-laws; better invite them in proper order or they’ll create hell.</p>
<p>I've not figured out the meaning of life yet, but l'm certain it ain't gonna happen while sitting around watching the TV.</p>
<p>Impossible (n): it's something which a small group quietly does while the general population has discarded as not capable.</p>
<p>If we find it hard to do, it's likely one of:
<ul>
<li>we're new to it</li>
<li>it's relatively a new thing</li>
<li>we're doing it wrong</li>
</ul>
</p>
<p>Cant' change, there will always be two groups: those who treat others nice & those who don't. But, it's our choice which we're part of.</p>
<p>The experience of a software developer is measured by how they minimize writing code while they maximize the desired result.</p>
<p>We can't change the past, can't hold on to the present, and can't avoid the future. The wise prepare ahead, knowing that.</p>
<p>Refactoring is but a second chance to improve the quality of code.</p>
<p>There are only two kinds of programmers: Those who code to live and those who live to code.</p>
<p>The shorter the video, the longer it takes to make it.</p>
<p>Duplicating code is duplicating work. Refactor and reuse.</p>
<p>Adding a feature to an app trumps any inflight entertainment.</p>
<p>There's no easier way to feel like an idiot than trying to use someone else's machine/keyboard.</p>
<p>There are always flaws in our code. Only choice's when we find 'em, during development with proper testing or in production, with chagrin.</p>
<p>It's wonderful to see these little classes fight to hold this new method and I get to decide the winner, at least for now.</p>
<p>Fear not the domain or the app context, for it's the accidental complexity of the solution space that's waiting to chew us up.</p>
<p>It’s amazing to work with people who get things done!</p>
<p>Every coder is a coincidental polyglot programmer, it matters to make that intensional and deliberate.</p>
<p>Imperative code is packed with accidental complexity.</p>
<p>A sign that the world has definitely gone crazy—every single language, even very old likable ones, wants to compile down to JavaScript.</p>
<p>Never name child or pet after a language. Any time they hear you go from "X, you're awesome" to "X, why? You suck" they get very confused.</p>
<p>Finding a good answer's a challenge, it requires posing the right set of questions. Hard part's often in figuring out the leading questions.</p>
<p>Having the patience to ask for clarification is superior compared to having the eagerness to deliver a judgement.</p>
<p>The best part of coffee is the aroma.</p>
<p>A significant part of our work involves dealing with human emotions, especially ones own.</p>
<p>If we can't name a variable or a function appropriately, it may be a sign we've not yet understood its true purpose.</p>
<p>Education should prepare us, not to answer silly questions, but to deliver real value and have the confidence to improve the status quo.</p>
<p>Glad this site's captcha wants me to prove that I'm not a robot. Good, I was worried it was gonna ask for a proof of being a human.</p>
<p>"Let me show you what I've done so far" is a great way to break the inertia and get moving.</p>
<p>Good teachers are always surrounded by students eager to teach them.</p>
<p>Living is the art of what you can tolerate.</p>
<p>Acceleration of learning is as important as accumulation of knowledge. Next to what we know, how quickly we can learn is very critical.</p>
<p>Humans are weird, they wanna grow up soon, so they can start complain they're getting older.</p>
<p>TIL: JavaScript is like that bad villain in a thriller, each time they think to have killed him he keeps coming back with greater vengeance.</p>
<p>The transition from "coding to make a living" to "living to master coding" is a wonderful journey.</p>
<p>Seek help when you hear that troubling inner voice that says "What random, cryptic, totally meaningless name can I give to this variable?"</p>
<p>It's a lot of fun when the wireless trackpad in the bag turns on suddenly and sends the mouse cursor in random directions.</p>
<p>When I was a kid, I used to tell scary stories. I’ve grown, now I tell people about programming.</p>
<p>The only things that seems perfect about static typing or dynamic typing is our biases towards/against either one of them.</p>
<p>An ambitious teacher does not desire to make the concepts stick to their pupil's mind, but to set it on fire.</p>
<p>The biggest problem is not recognizing there’s a systemic problem.</p>
<p>We can give more time or better quality but rarely both.</p>
<p>The most frustrating part for me is my ignorance of the depth of my ignorance.</p>
<p>Over the years I've learned that good writers write in short paragraphs.</p>
<p>When writing, don't count words, instead make the words count.</p>
<p>What matters the most is not our capability to predict the future, but it's the ability to adapt as it arrives.</p>
<p>We're quick to point the cost of creating quality, but are often in denial about the cost and consequences of not having it.</p>
<p>There's no other human duty of higher precedence than treating any fellow human with dignity.</p>
<p>Hope is knowing that you can make a difference in other peoples lives, like the way someone else did for your own.</p>
<p>Think of it as an attempt than a failure.</p>
<p>Nothing restores faith in humanity as when you see common people do small nice things very quietly.</p>
<p>Learning from failures is the key to success. It needs right attitude & sufficient time. Start early, fail fast & often to apply learnings.</p>
<p>Programming is an intense test of perseverance.</p>
<p>Our worst enemies are our own wrong convictions.</p>
<p>Significant part of experience is unlearning the practices we shouldn't have learned in the first place.</p>
<p>Software developer: someone who gets paid to program and then more to fix it.</p>
<p>The thought that something can be better and making it happen can be within our sphere of influence is the birth of a wonderful ray of hope.</p>
<p>Gentle reminder, there is a real human at the other end of your email. Connect, then converse. Don't treat them like they're an automaton.</p>
<p>Code is how we tell our colleagues how we feel about them.</p>
<p>That moment when your mind congratulates your packing skill and, at the same time, your eyes catch items forgotten on the counter.</p>
<p>In general, our minds don’t see solutions as clearly when we approach deadlines.</p>
<p>I'm marginally good at what I do well, but when it comes to things I suck at, I am exceptional in that direction.</p>
<p>Every technical decision should have an expiration label on it.</p>
<p>1000s of years & we're still not done learning & changing in other aspects of life. Don't sweat things are changing in our nascent field.</p>
<p>Type inference is a feature of the compiler that lets you communicate like an adult.</p>
<p>Conceptualizing is very important but quickly getting to create is a great way to learn how to create it better.</p>
<p>Watching a child turn into a responsible adult is a true gift of living.</p>
<p>Each of us have to make a hard decision: to live the life we desire or the one others desire for us.</p>
<p>We enjoy coding not because it is easy; it's the challenges, and our genuine resolve to tackle them, that keep us going.</p>
<p>Sometime the problem is not entirely outside but within.</p>
<p>No amount of thinking can fully replace the learnings that come from trying. Trying complements thinking.</p>
<p>Years of education often helps us to find a job but fails to help us find ourselves.</p>
<p>No wonder the language was not very forgiving when I mistyped splitOn as spitOn.</p>
<p>There are rules and then there are exceptions. Experience is knowing which option to exercise when.</p>
<p>Nature is the ultimate beauty and it’s a humbling experience to admire it.</p>
<p>Watching someone learn is in itself a great learning experience.</p>
<p>Today's experience is tomorrow's story.</p>
<p>Life is not kind to a lot of people. Don't forget to be grateful for and to enjoy what we have.</p>
<p>IMHO, words like awesome, badass, incredible, great, exceptional,... are nice to use to describe other people's work, but not ones own.</p>
<p>Each one of us is given an undisclosed, non-renewable, amount of a precious wealth—Time; we can't ask for more, don't squander it.</p>
<p>Writing bad lambdas gives lambdas a bad name.</p>
<p>Whether a topic is theoretically or practical may depend more on the presenter than on the topic.</p>
<p>Never punish those who show up on time by asking to wait for those who are tardy.</p>
<p>Willingness to learn is both an acknowledgement of our current ignorance and ability/desire to address it.</p>
<p>Hearing "wars," as a kid, I thought humans are awesome, fighting alien robots. Then, I found they're plain stupid, just fighting each other.</p>
<p>It's easy to throw up the hands when something does not work. But, putting the hands, and the heads, together often gets better results.</p>
<p>There is no trying, there is only retrying.</p>
<p>There's no point waking up to live someone else's dreams.</p>
<p>While some languages prevent us from shooting ourselves in the foot, other languages sadly make it easy to blow up an entire village.</p>
<p>Trying to acquire knowledge without critical thinking is like trying to strike matches in vacuum.</p>
<p>Planning is very important; what matters is not how meticulous we're in creating it, but how agile we are in adapting it to the realities.</p>
<p>Ignorance is easier to cure than lack of civility. Also, ignorance is harder to cure in the absence of civility.</p>
<p>A constructive criticism elevates the critique and the criticized. A non-constructive comment lower the critique and the criticism.</p>
<p>Different result needs different actions.<br>
Different actions need different attitude.<br>
Start with attitudes to effect change.</p>
<p>Take all the trouble you can to help others and not all the help you can to trouble others.</p>
<p>The world is too big and life too short to be huddled in a dark corner of hatred, bigotry, and violence.</p>
<p>If you complain a lot, you may end up<br>
<br>
- spending a lot of time alone, or<br>
- in the company of other whiners<br>
<br>
Neither option seem exciting.</p>
<p>We can learn from every one; some teach us how to live and yet some teach how not to.</p>
<p>
Phases of growing up:<br>
- l know nothing<br>
- I know everything<br>
- There's so much more to learn<br></p>
</div>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com3tag:blogger.com,1999:blog-3088609713768060708.post-74882750859933592202016-06-29T04:00:00.001-06:002016-06-29T04:00:10.305-06:00Infinite Streams May Remove Accidental Complexity<a href="https://twitter.com/share" class="twitter-share-button" data-text="Infinite Streams May Remove Accidental Complexity" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<p>We discussed how lazy evaluations may lead to infinite streams <A href="http://blog.agiledeveloper.com/2016/06/lazy-evaluation-make-infinite-streams.html">in the previous post</A>. In this post we see how it can help make code more expressive, fluent, and reduce accidental complexity in some cases.</p>
<p>Let's start with an initial sample code.</p>
<pre style="background-color: #f0f0f0;"><code>import java.util.*;
import java.util.stream.*;
public class Sample {
public static boolean isPrime(int number) {
return number > 1 &&
IntStream.range(2, number)
.noneMatch(i -> number % i == 0);
}
public static void main(String[] args) {
}
}
</code></pre>
<p>The purpose of the <code>isPrime</code> function is pretty obvious. We will make use of this soon in the functions we'll write. Let's move forward.</p>
<p>Try coding the following exercise in imperative style without looking at the code below and measure the time it takes for you to write it. Also, after completing, show a fellow programmer the imperative code and see how long they take to figure out what the code is doing.</p>
<p>Given two <code>int</code> parameters <code>n</code> and <code>k</code>, write a function named <code>compute1</code> that computes the sum of square root of <code>k</code> prime numbers starting with <code>n</code>.</p>
<p>Take a break from further reading and code the above function. When you're done and noted the time it takes, move forward.</p>
<p>Now, let us write that function here together, will start with the function declaration first:</p>
<pre style="background-color: #f0f0f0;"><code>public static double compute1(int n, int k) {
}
</code></pre>
<p>We have to look for primes starting with <code>n</code>. So, we'll create a variable <code>index</code> to hold the value as it changes through the iteration. We also need to keep track of the number of primes, let's define a variable named <code>count</code> for that. Both these variables go within the <code>compute1</code> function.</p>
<pre style="background-color: #f0f0f0;"><code>int index = n;
int count = 0;
</code></pre>
<p>Now comes the fun part, the looping:</p>
<pre style="background-color: #f0f0f0;"><code>while(count < k) {}
</code></pre>
<p>Time to pause, grimace, scratch head...<i>is it < or <= ?</i> We ask that question each and every time we write such comparison, sigh. Take time to reason, we start with <code>0</code>, so...</p>
<p>The next step, we need to implement the loop, but we also need another variable to store the sum of the square root values, let's change the function accordingly:</p>
<pre style="background-color: #f0f0f0;"><code>public static double compute1(int n, int k) {
int index = n;
int count = 0;
double result = 0;
while(count < k) {
if(isPrime(index)) {
result += Math.sqrt(index);
}
}
}
</code></pre>
<p>We're almost done, but the last few steps will test any patience left in us. We need to increment the count:</p>
<pre style="background-color: #f0f0f0;"><code>while(count < k) {
if(isPrime(index)) {
result += Math.sqrt(index);
count++;
}
}
</code></pre>
<p>We're not done. Don't forget to increment the <code>index</code> variable:</p>
<pre style="background-color: #f0f0f0;"><code>while(count < k) {
if(isPrime(index)) {
result += Math.sqrt(index);
count++;
index++;
}
}
</code></pre>
<p>oops, that won't work. Need to increment <code>count</code> when we find a prime number, but need to increment the <code>index</code> for each step through the iteration. Let's change the code and also return <code>result</code>:</p>
<pre style="background-color: #f0f0f0;"><code>public static double compute1(int n, int k) {
int index = n;
int count = 0;
double result = 0;
while(count < k) {
if(isPrime(index)) {
result += Math.sqrt(index);
count++;
}
index++;
}
return result;
}
</code></pre>
<p>Is that correct? Programmers are some of the smartest people—they'll never say <i>yes</i> to that question. You will here them say <i>"it looks good"</i>. That way if we later find that it's broken, we don't have to feel as embarrassed.</p>
<p>That's a lot of dancing around to get this code right. The given problem is rather a simple one, but the solution does not appear simple. This is accidental complexity. Inherent complexity comes from the problem and the domain. Accidental complexity, on the other hand, comes from the solution we use.</p>
<p>Soon after you write the code, you stare at it, asking is this right, did I miss something? The more we try to do, the more complex the code can get. It's code like this that pushes some developers to prematurely become managers.</p>
<p>Not only does this code take effort to write, it takes effort to read and understand also.</p>
<p>Let's write another version of this logic, using the functional style—with infinite streams.</p>
<pre style="background-color: #f0f0f0;"><code>public static double compute2(int n, int k) {
return Stream.iterate(n, e -> e + 1)
.filter(Sample::isPrime)
.limit(k)
.mapToDouble(Math::sqrt)
.sum();
}
</code></pre>
<p>Let's walk through the code—we need only one pass or sweep through the code, top-down. Create an infinite stream starting with <code>n</code>, filter only prime numbers, but limit the size of the stream to only <code>k</code> elements. Less than <code>k</code>? Less than or equal to <code>k</code>? You say "it's <code>k</code>, damn it, let's move on." OK, then transform the stream of <code>k</code> primes into a stream of square root of the primes and sum the values. It's that simple.</p>
<p>The code begins to read like the problem statement—it poses less impedance than the imperative version.</p>
<p>This is one example where infinite stream reduces complexity and makes code fluent and expressive. As we begin to get comfortable with functional programming, and infinite streams along the way, we'll find surprising places where infinite streams come to our rescue. The little optimist in me sees the opportunities to be well—infinite.</p>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com0tag:blogger.com,1999:blog-3088609713768060708.post-59839302047592773452016-06-22T04:00:00.000-06:002016-06-29T04:18:07.295-06:00Lazy Evaluation make infinite streams possible<a href="https://twitter.com/share" class="twitter-share-button" data-text="Lazy Evaluation make infinite streams possible" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<p>In the <A href="http://blog.agiledeveloper.com/2016/06/lazy-evaluation-may-make-code-more_15.html">previous post</A> we saw how lazy evaluation may make the code expressive without losing on performance. Here we'll see yet another benefit of lazy evaluations—Infinite Streams.</p>
<p>Streams may be unbounded or unrestricted in size. Let's look at a snippet of code first:</p>
<pre style="background-color: #f0f0f0;"><code>Stream.iterate(1, e -> e + 1)
</code></pre>
<p>We're calling the <code>iterate()</code> method of the <code>java.util.stream.Stream</code> interface, passing a value <code>1</code> and a lambda expression as arguments. This code snippet creates an infinite stream—it starts with the value <code>1</code>, and may further yield a series of values <code>2, 3, 4, 5, 6, 7,...</code></p>
<p>The stream is infinite in length. "<b>Infinite?</b>" you say, "then where would you store it?" <i>On the cloud of course</i>.</p>
<p>It would not make sense to eagerly create an infinite stream, after all. We would run out of time, patience, memory,... and much more. The infinite streams simply say "I can produce an infinite amount of data and I dare you to ask for all of them."</p>
<p>Infinite stream are highly practical—they rely on the fact that we will only ask for finite amount of data and they produce the data just-in-time, on demand, lazily.</p>
<p>Let's expand the code snippet just a bit:</p>
<pre style="background-color: #f0f0f0;"><code>System.out.println(
Stream.iterate(1, e -> e + 1)
.filter(e -> e > 1000)
.findFirst()
.orElse(0));
</code></pre>
<p>This code gets an infinite stream that yields values starting with <code>1</code> and filters out any values from the stream that are less than or equal to <code>1000</code>. The result of the <code>filter</code> operation is another infinite stream. Remember from the <A href="http://blog.agiledeveloper.com/2016/06/lazy-evaluation-may-make-code-more_15.html">previous post</A> that the <code>filter</code> method is an intermediate operation and it will not evaluate right away. In this example, the evaluation of both the lambda expression presented to <code>iterate</code> and the one passed to <code>filter</code> are lazy. It's the call to the terminal function <code>findFirst</code> that triggers the computation of both of these lambda expressions, but only just enough times for the terminal function to be satisfied.</p>
<p>The result of this code is a value of <code>1001</code>.</p>
<p>Infinite streams will not be possible without the capability to perform lazy evaluations. It is our responsibility, however, to make sure that the number of evaluations are actually finite. For example, while it makes sense to query a bounded or finite stream for its size—using the <code>count</code> method—it would not make sense to call that method on an infinite stream. For example:</p>
<pre style="background-color: #f0f0f0;"><code>System.out.println(Arrays.asList(1, 2, 3).stream().count()); // prints 3
System.out.println(Stream.iterate(1, e -> e + 1).count()); // ...eternity
</code></pre>
<p>We took a peek at what makes infinite streams possible. In <A href="http://blog.agiledeveloper.com/2016/06/infinite-streams-may-remove-accidental_29.html">the next post</A> we will look at an example of how infinite streams can make code highly expressive and remove some accidental complexities.</p>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com0tag:blogger.com,1999:blog-3088609713768060708.post-5547725015228418932016-06-15T04:00:00.000-06:002016-06-22T04:45:04.376-06:00Lazy Evaluation: may make code more expressive without losing on efficiency: Part II<a href="https://twitter.com/share" class="twitter-share-button" data-text="Lazy Evaluation: may make code more expressive without losing on efficiency: Part II" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<p>In the <A href="http://blog.agiledeveloper.com/2016/06/lazy-evaluation-may-make-code-more.html">Part I</A> we converted an imperative code to a more expressive functional code and ended with a question about efficiency. Let's pick up this blog from where we left.
<p>Here's the imperative version of the code, again:</p>
<pre style="background-color: #f0f0f0;"><code>public static Integer computeImperative(List<Integer> numbers) {
Integer result = null;
for(int e : numbers) {
if(e > 3 && e % 2 == 0) {
result = e * 2;
break;
}
}
return result;
}
</code></pre>
<p>Let's see the number of operations this code will perform if the given list has the values <code>(1, 2, 3, 5, 4, 6, 7, 8, 9, 10)</code>, in that order. The check <code>> 3</code> will fail for the first three values and so the even check will not be done for those. That's <code>3</code> computations so far. For <code>5</code>, it will perform both the checks in the <code>if</code> condition, so that's two more operations. For <code>4</code> it will perform the two checks and then the multiplication. That's <code>3</code> more computations and the code will hit the <code>break</code> right after that. That's <code>3 + 2 + 3</code>, a total of <code>8</code> operations.</p>
<p>We implemented a functional version of this code in the <A href="http://blog.agiledeveloper.com/2016/06/lazy-evaluation-may-make-code-more.html">previous blog</A>. It was expressive and elegant, easier to read and understand. But, we were curious about its performance. Would it perform more operations, spend more time and effort to compute the result.</p>
<p>The short answer is, it could, but it does not have to. Let's see how.</p>
<p>We will first implement the functional style code using Ruby---which supports both imperative and functional style of programming.</p>
<pre style="background-color: #f0f0f0;"><code>def is_greater_than_3?(number)
puts "is_greater_than_3 called for #{number}"
number > 3
end
def is_even?(number)
puts "is_even? called for #{number}"
number % 2 == 0
end
def double_value(number)
puts "double_value called for #{number}"
number * 2
end
def compute(numbers)
numbers.find_all { |e| is_greater_than_3?(e) }
.find_all { |e| is_even?(e) }
.map { |e| double_value(e) }
.first
end
numbers = [1, 2, 3, 5, 4, 6, 7, 8, 9, 10]
puts compute(numbers)
</code></pre>
<p>We created small functions for each of the operations—the two checks and for the multiplication. In each of the functions we have a print statement, <code>puts</code>, for illustration purpose. In the <code>compute</code> function we use function composition. <code>find_all</code> is equivalent to the <code>filter</code> function.</p>
<p>To run the code, use the command <code>ruby sample.rb</code> where <code>sample.rb</code> is the file which contains the code.</p>
<p>This example does not show Ruby in it's best light, but that's not the intention. I like Ruby and use it quite extensively. It's great for many things. It's also a language that makes code concise and highly expressive. But, this example shows one of the drawbacks as well.</p>
<p>Here's the output from a run of the code:</p>
<pre style="background-color: #f0f0f0;"><code>is_greater_than_3 called for 1
is_greater_than_3 called for 2
is_greater_than_3 called for 3
is_greater_than_3 called for 5
is_greater_than_3 called for 4
is_greater_than_3 called for 6
is_greater_than_3 called for 7
is_greater_than_3 called for 8
is_greater_than_3 called for 9
is_greater_than_3 called for 10
is_even? called for 5
is_even? called for 4
is_even? called for 6
is_even? called for 7
is_even? called for 8
is_even? called for 9
is_even? called for 10
double_value called for 4
double_value called for 6
double_value called for 8
double_value called for 10
8
</code></pre>
<p>While Ruby supports functional style, it does not readily perform lazy evaluations. As a result, it performs redundant computations for the given example list. The first use of <code>find_all</code> function created a new list from the given list. We can see the <code>is_greater_than_3</code> is called <code>10</code> times, once for each element. Then, the second use of <code>find_all</code> works with a list of seven elements to create a third list with only even numbers. The <code>double_value</code> is called for each element on this resulting list to create yet another list of values doubled. The final call to <code>first</code> returns only the first value in the final collection and discards the remaining values. We expended a total of <code>21</code> operations. In contrast, the imperative style only performed <code>8</code> operations for the same list of values.</p>
<p>If we add more elements to this list, the imperative style will not perform any extra operations. The Ruby functional style will, however.</p>
<p>For large collections, this may appear to be cost prohibitive. Are we forced to compromise on performance for elegance then?</p>
<p>Thankfully, not all languages that offer functional style exhibit the same behavior. A good number of languages, including Java, provide lazy evaluation in addition to function composition.</p>
<p>Let's reimplement the Ruby version in Java. A key strength of Java's <code>Stream</code> API is lazy evaluation. We'll see that in action here:</p>
<pre style="background-color: #f0f0f0;"><code>import java.util.*;
public class Sample {
public static boolean isGreaterThan3(int number) {
System.out.println("isGreaterThan3 called for " + number);
return number > 3;
}
public static boolean isEven(int number) {
System.out.println("isEven called for " + number);
return number % 2 == 0;
}
public static int doubleValue(int number) {
System.out.println("doubleValue called for " + number);
return number * 2;
}
public static Optional<Integer> compute(List<Integer> numbers) {
return numbers.stream()
.filter(Sample::isGreaterThan3)
.filter(Sample::isEven)
.map(Sample::doubleValue)
.findFirst();
}
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
System.out.println(
compute(numbers).map(Object::toString)
.orElse("No value"));
}
}
</code></pre>
<p>Each of the small methods in this version do the same thing as their Ruby counterpart. In the <code>compute</code> method we've used function composition to first filter the values greater than 3, then even numbers, then doubled the resulting values, and in the end obtained the first value from the final collection. These steps in Java are just the same as the steps we used in the Ruby version. However, there's a significant semantical difference between how Ruby evaluates the expressions in its function composition versus how the expressions in Java <code>Stream</code>'s function composition are evaluated. The <code>Stream</code> is inherently lazy.</p>
<p>The behavior of the <code>Stream</code> is much like my teen age children—they don't act on things when they're told.</p>
<p>Here's a scenario from an evening at my home. My ever-so-patient wife to my teen:</p>
<p>"Please turn off the TV"</p>
<p>It's like no words were spoken; nothing happened.</p>
<p>"Clean up around you."</p>
<p>Chirp, chirp, nothing happened.</p>
<p>"Do your homework."</p>
<p>...sound of silence here...</p>
<p>"I'm calling your dad."</p>
<p>Suddenly the TV gets turned off and things start moving...</p>
<p>On occasions, it's me replacing my wife's <code>callingDaddy()</code> with <code>IWillTellMomAboutThis()</code>.</p>
<p>The <code>Stream</code> is just like that. You call <code>filter</code>, nothing really happened, no filtering, no conversion of given collection to an intermediate collection. Same with the next call to <code>filter</code> and the subsequent call to the <code>map</code> function. They might as well have renamed the <code>findFirst</code> function as <code>callAParent</code>—it's the call to these <i>terminal</i> functions that trigger the evaluation, <i>lazily</i>.</p>
<p>When <code>findFirst</code> is called, the execution of the function chain is triggered. However, the sequence of evaluation is quite different from what appears to our eyes. Instead of the entire collection going through the first <code>filter</code> operation, the sequence of functions in the chain is applied to one element at a time, but only until the terminal operation is satisfied.</p>
<p>In the given example, the first element in the collection, <code>1</code> is passed through the first filter operation. Since it's not greater than <code>3</code>, the next value in the collection is taken up. Since all the first three values are not greater than <code>3</code>, after evaluating the <code>isGreaterThan3</code> function on each one of them, the value <code>5</code> is next considered. This value goes successfully through the first filter operation but fails the second operation of <code>isEven</code>. That's a total of five operations so far. Next, the value <code>4</code> from the collection is taken up. It successfully goes through both the filters and reaches the <code>findFirst</code> operation. Since that satisfies the terminal method, the evaluation of this function composition terminates at this point, after a total of <code>8</code> operations. Here's the output from the execution of the Java version:</p>
<pre style="background-color: #f0f0f0;"><code>isGreaterThan3 called for 1
isGreaterThan3 called for 2
isGreaterThan3 called for 3
isGreaterThan3 called for 5
isEven called for 5
isGreaterThan3 called for 4
isEven called for 4
doubleValue called for 4
8
</code></pre>
<p>The functional style version in Java took the same number of steps during execution as the imperative version did, thanks to the execution being lazy.</p>
<p>We did not have to compromise on performance in order to benefit from the expressive power of functional style in Java. Languages and/or libraries in Java, C#, Scala, Haskell, F#,... and many more offer lazy evaluation. While embracing functional style of programming we have to take the time to explore if lazy evaluation is possible. Laziness has a great impact on the semantics and also on efficiency.</p>
<p>When used in the context of functional programming, the words lazy may be pronounced as <i>efficient</i>.</p>
<p>In <A href="http://blog.agiledeveloper.com/2016/06/lazy-evaluation-make-infinite-streams.html">the next blog we will see how lazy evaluation may lead to infinite streams</A>.</p>
Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com3tag:blogger.com,1999:blog-3088609713768060708.post-73093399364716805412016-06-08T10:34:00.001-06:002016-06-15T07:39:17.926-06:00Lazy Evaluation: may make code more expressive without losing on efficiency: Part I<a href="https://twitter.com/share" class="twitter-share-button" data-text="Lazy Evaluation: may make code more expressive without losing on efficiency: Part I" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<p>In a <A href="http://blog.agiledeveloper.com/2016/06/benefits-of-pure-functions-can-be-lazy.html">previous blog</A> we discussed how pure functions may enjoy lazy evaluations and mentioned a few benefits of being lazy. In this blog we discuss the first benefit: expressive code without losing on efficiency.</p>
<p>Let's first take a look at an example code:</p>
<pre style="background-color: #f0f0f0;"><code>import java.util.*;
public class Sample {
public static Integer computeImperative(List<Integer> numbers) {
Integer result = null;
for(int e : numbers) {
if(e > 3 && e % 2 == 0) {
result = e * 2;
break;
}
}
return result;
}
//...
}
</code></pre>
<p>The <code>computeImperative</code> method takes a list of <code>Integer</code> values and returns an <code>Integer</code>. But what does it really do?</p>
<p>By examining the loop and the <code>if</code> statement, we can figure out that it returns the double of the first even number greater than 3 from the given list. If the list were empty or if no number makes the cut, then <code>null</code> is returned. Also, the loop will terminate as soon as it finds a candidate element.</p>
<p>Let's take a look at the <code>main</code> method that uses the <code>computeImperative</code> method.</p>
<pre style="background-color: #f0f0f0;"><code> public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
int doubleOfFirstEvenGreaterThan3 = computeImperative(numbers);
System.out.println(doubleOfFirstEvenGreaterThan3);
}
</code></pre>
<p>In <code>main</code> we call the <code>computeImperative</code> method and stored the result in an <code>int</code> variable. But, this is trouble waiting to happen. If the result of the method call were <code>null</code>, then this code will face a misserable <code>NullPointerException</code> at runtime.</p>
<p>The code is imperative in style and carries with it all the <A href="http://blog.agiledeveloper.com/2015/07/the-imperative-style.html">smells of that style of programming</A>. Let's implement <A href="http://blog.agiledeveloper.com/2015/08/prefer-functional-style-over-imperative.html">a functional style</A> version of this method.</p>
<pre style="background-color: #f0f0f0;"><code> public static Optional<Integer> computeFunctional(List<Integer> numbers) {
return numbers.stream()
.filter(e -> e > 3)
.filter(e -> e % 2 == 0)
.map(e -> e * 2)
.findFirst();
}
</code></pre>
<p>This version is a lot easier to read and understand than the imperative version. We can, in one sweep from top to the bottom, read out the task performed by this method: Given a collection of numbers, filter the numbers greater than 3, then filter numbers that are even, double the values, and finally return just the first element in the result.</p>
<p>The code is not only expressive, it's much safer to use as well. The result of <code>findFirst</code> is an <code>Optional<T>.</code> An <code>Optional</code> may contain a value, of parameterized type <code>T</code>, or may be empty. We can't directly assign an <code>Optional</code> to a variable of type <code>T</code>. This prevents accidental <code>NullPointerException</code> at runtime. Instead, we have to program deliberately, and extract the value out of the <code>Optional</code> and along the way handle the possibility of the value not being present.</p>
<p>Let's change the <code>main</code> method to use the functional style <code>computeFunctional</code>:</p>
<pre style="background-color: #f0f0f0;"><code> public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
Optional<Integer> doubleOfFirstEvenGreaterThan3 =
computeFunctional(numbers);
System.out.println(
doubleOfFirstEvenGreaterThan3.map(Object::toString)
.orElse("No result"));
}
</code></pre>
<p>In <code>main</code> we call <code>computeFunctional</code>, convert the value, if present, in the resulting <code>Optional</code> to a <code>String</code>. We print that converted value or else, that is, if the value were not present, print a message "No result."</p>
<p>The code is expressive compared to the imperative version. It's functional in style and uses function composition. However, there's a deep rooted concern in this code. How much more work does this code do when compared to the imperative version? Are we trading a greater inefficiency for greater expressiveness.</p>
<p>We'll answer that question of <A href="http://blog.agiledeveloper.com/2016/06/lazy-evaluation-may-make-code-more_15.html">efficiency in the next blog</A>.</p>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com0tag:blogger.com,1999:blog-3088609713768060708.post-59447984349349245232016-06-01T04:00:00.000-06:002016-06-08T10:35:38.069-06:00Benefits of Pure Functions: Can be Lazy<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="https://twitter.com/share" class="twitter-share-button" data-text="Benefits of Pure Functions: Can be Lazy" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<p>In a <A href="http://blog.agiledeveloper.com/2016/05/benefits-of-pure-functions-easier-to.html">previous related blog</A> we discussed how pure functions are easier to parallelize. In this blog, we discuss another benefit <A href="http://blog.agiledeveloper.com/2015/12/benefits-of-pure-functions.html">from this list</A>: pure functions can be lazy.</p>
<p>Lazy evaluation is where a program may postpone evaluating an expression until just-in-time when it's value is needed. If the value is never needed during the execution of the program, the evaluation of the expression may be totally skipped.</p>
<p>Languages like Haskell perform lazy evaluations more naturally. In C# and Scala we can mark some variable bindings as lazy. In other languages, we have to work just a little harder to make variable bindings lazy.</p>
<p>Let's take a look at a short Scala example:</p>
<pre style="background-color: #f0f0f0;"><code>def compute(number: Int) = {
//assume this is time consuming
Thread.sleep(5000)
number
}
val start = System.nanoTime
if(Math.random() > 0.5 && compute(5) > 0)
System.out.println("computed");
else
System.out.println("skipped");
val end = System.nanoTime
println(s"Time taken: ${(end - start)/1e9}")
</code></pre>
<p>We'll assume that the <code>compute</code> function is a time consuming function—we better not call it unless it's result is really needed. When the program is run, depending on the value returned by the <code>random()</code> method, the function is either evaluated or skipped. Lets run the program a couple of time and see the output:</p>
<pre style="background-color: #f0f0f0;"><code>> scala sample.scala
computed
Time taken: 5.003096089
> scala sample.scala
skipped
Time taken: 1.75862E-4
>
</code></pre>
<p>If the value returned by <code>random()</code> is less than or equal to <code>0.5</code>, then the evaluation of the <code>compute()</code> function is skipped. The executions where the call is skipped will take far less time than in which the call is evaluated.</p>
<p>We know the concept we just saw as <i>short-circuit evalution</i>. Short-circuit evaluation is performed in most mainstream languages in use today.</p>
<p>Let's change the example a tad, by introducing a temporary variable, like so:</p>
<pre style="background-color: #f0f0f0;"><code>val temp = compute(5)
if(Math.random() > 0.5 && temp > 0)
System.out.println("computed");
else
System.out.println("skipped");
</code></pre>
<p>The result of the evaluation of <code>compute()</code> is now first stored in the variable <code>temp</code>, before the evaluation of the condition in <code>if</code>. Multiple runs of the code will take about the same time as we see in the output:</p>
<pre style="background-color: #f0f0f0;"><code>> scala sample.scala
computed
Time taken: 5.004494657
> scala sample.scala
skipped
Time taken: 5.002012277
>
</code></pre>
<p>Even if the value of <code>temp</code> is not used, we incur the overhead of determining a value for it, due to <i>eager</i> evaluation of the <code>compute()</code> function.</p>
<p>We can tell Scala to be lazy about calling the <code>compute()</code> function. Let's change the code once more:</p>
<pre style="background-color: #f0f0f0;"><code>lazy val temp = compute(5)
</code></pre>
<p>We added the word <i>lazy</i> in front of the declaration of the variable <code>temp</code>. Scala now postponed binding the variable to its value until we're ready to use the variable. Let's run the code a couple of time and view the results:</p>
<pre style="background-color: #f0f0f0;"><code>> scala sample.scala
skipped
Time taken: 1.84514E-4
> scala sample.scala
computed
Time taken: 5.004431085
>
</code></pre>
<p>Even though we called <code>compute()</code> before we entered the evaluation of the condition in <code>if</code>, the actual execution of the function was postponed until its value was actually used. If the value was not used, the execution was skipped.</p>
<p>Before we can rejoice about laziness of evaluations, there's one thing we have to be very careful about. Lazy evaluation makes sense only if the functions, whose evaluation are being postponed, are pure.</p>
<p>Let's take a look at yet another example to illustrate this point.</p>
<pre style="background-color: #f0f0f0;"><code>def increment(number: Int) = number + 1
var x = 5
val result = increment(x)
if(Math.random() > 0.5) {
println("changed")
x = 77
} else {
println("unchanged")
}
println(result)
</code></pre>
<p>No matter how many times we run this code, the value printed out by the last line will be exactly the same:</p>
<pre style="background-color: #f0f0f0;"><code>> scala sample.scala
changed
6
> scala sample.scala
unchanged
6
>
</code></pre>
<p>Converting the binding of the variable <code>result</code> from an eager evaluation to a lazy evaluation will not make sense:</p>
<pre style="background-color: #f0f0f0;"><code>lazy val result = increment(x)
</code></pre>
<p>After this change, we can't quite predict the value of the <code>result</code> variable:</p>
<pre style="background-color: #f0f0f0;"><code>> scala sample.scala
unchanged
6
> scala sample.scala
changed
78
>
</code></pre>
<p>The expression that's presented for lazy evaluation is not pure—it depends on a mutable variable. This variable may change at any time, in the current thread or in other threads. It may change before the evaluation of the function slated for lazy evaluation. And, it may change after. Or while the function is being evaluated—oops.</p>
<p>If a function is pure, you may evaluate it now or safely evaluate it later. Furthermore, you can save the value of evaluation and reuse it since it will have the same result no matter how many times we evaluate it. Also, if a function has no side-effect, the only way anyone will know if the function was evaluated or not is by looking at the result. So, the execution can be safely postponed as desired.</p>
<center><b style="background-color: #f0f0f0;">Pure functions can be lazily evaluated.</b></center>
<p>We saw an example in Scala in this blog. We'll take a look at some lazy evaluation examples in Java in the following blogs related to this topic.</p>
<p><A href="http://blog.agiledeveloper.com/2015/12/benefits-of-pure-functions.html">In this series of blogs</A>, we've looked at six benefits of pure functions. The last benefit we saw—pure functions can be lazy—leads to more benefits of its own.</p>
<p>Lazy evaluations:</p>
<ui>
<li><A href="http://blog.agiledeveloper.com/2016/06/lazy-evaluation-may-make-code-more.html">may make code more expressive without losing on efficiency</A></li>
<li>make infinite streams possible</li>
</ui>
<p>We will discuss these benefits of lazy evaluation in the future blogs.</p>
</div>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com0tag:blogger.com,1999:blog-3088609713768060708.post-46609503921260156492016-05-25T04:00:00.000-06:002016-06-01T06:35:14.727-06:00Benefits of Pure Functions: Easier to Parallelize<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="https://twitter.com/share" class="twitter-share-button" data-text="Benefits of Pure Functions: Easier to Parallelize" data-size="large">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<p>In a <A href="http://blog.agiledeveloper.com/2016/02/benefits-of-pure-functions-memoizable.html">previous related blog</A> we discussed how pure functions are memoizable. In this blog, we discuss another benefit <A href="http://blog.agiledeveloper.com/2015/12/benefits-of-pure-functions.html">from this list</A>: pure functions are easier to parallelize.</p>
<p>Functional style of programming makes code more expressive and concise. As we get more comfortable with functional style, where it makes sense, we can lean more towards functional style instead of the imperative style. However, we have to be careful to avoid impure lambda expressions. Let's discuss with an example.</p>
<p>Here's a piece of code that computes the sum of square root of prime numbers from 2 to a given number:</p>
<pre style="background-color: #f0f0f0;"><code>import java.util.*;
import java.util.stream.IntStream;
public class Sample {
private static double sumOfSqrtsOfPrimes = 0.0;
public static boolean isPrime(int number) {
return number > 1 &&
IntStream.range(2, number)
.noneMatch(i -> number % i == 0);
}
public static void main(String[] args) {
int number = 500000;
long start = System.nanoTime();
for(int i = 1; i <= number; i++) {
if(isPrime(i))
sumOfSqrtsOfPrimes += Math.sqrt(i);
}
long end = System.nanoTime();
System.out.printf("Time Taken: %g sec\n", (end - start)/1e9);
System.out.println(sumOfSqrtsOfPrimes);
}
}
</code></pre>
<p>The code within the <code>main()</code> function is imperative in style. It sequentially iterates through each number from <code>1</code> to the given <code>number</code>. It computes the square root of each prime number it finds in that range and adds the value to the <code>sumOfSqrtsOfPrimes</code> variable.</p>
<p>Let's run the code to see how long this code takes to run.</p>
<pre style="background-color: #f0f0f0;"><code>Time Taken: 64.6315 sec
1.896851199544097E7
</code></pre>
<p>It took a little over a minute to run. Let's now change the code in <code>main()</code> from imperative to functional style, but rather naively.</p>
<pre style="background-color: #f0f0f0;"><code> public static void main(String[] args) {
int number = 500000;
long start = System.nanoTime();
IntStream.rangeClosed(1, number)
.boxed()
.filter(Sample::isPrime)
.map(Math::sqrt)
.forEach(value -> sumOfSqrtsOfPrimes += value); //This is bad
long end = System.nanoTime();
System.out.printf("Time Taken: %g sec\n", (end - start)/1e9);
System.out.println(sumOfSqrtsOfPrimes);
}
</code></pre>
<p>First, we get a range of values using the <code>rangeClosed</code> method of <code>IntStream</code>, convert that to a <code>Stream<Integer></code> using the <code>boxed()</code> function. Then we filter the <code>Stream<Integer></code> to get only prime numbers, then compute the square root of those values. All is well so far in the code. In the final step, however, we provide to <cod>forEach</code> a lambda expression that's impure. It mutates the variable <code>sumOfSqrtsOfPrimes</code>. We'll discuss the consequence of this shortly, but first let's run the code and check on the result and performance.</p>
<pre style="background-color: #f0f0f0;"><code>Time Taken: 45.8868 sec
1.896851199544097E7
</code></pre>
<p>The result of the computation is exactly the same. The time is better as well, but this solution is sequential much like the imperative solution.</p>
<p>Compared to the imperative solution, the functional solution is much easier to parallelize. In order to parallelize the imperative solution we have to manage a pool of threads and schedule the execution on different threads. In the functional solution, we can simply ask for the execution to be parallelized. That fits well with the spirit of functional style—tell what we want without getting into the details of how to do that.</p>
<p>Unfortunately, there's a catch as we'll see soon.</p>
<p>Let's parallelize the execution of this code first.</p>
<pre style="background-color: #f0f0f0;"><code>IntStream.rangeClosed(1, number)
.boxed()
.parallel()
.filter(Sample::isPrime)
.map(Math::sqrt)
.forEach(value -> sumOfSqrtsOfPrimes += value); //This is bad
</code></pre>
<p>We only had to make a small change—inserted a call to <code>parallel()</code> right before calling the <code>filter()</code> operation. Now, instead of sequentially working on each of the number in the range, the operations will be performed in parallel. The number of threads on which the operations will be scheduled, by default, depends on the number of cores on the system. The program should run faster. Let's take a look at the result of the run.</p>
<pre style="background-color: #f0f0f0;"><code>Time Taken: 11.6477 sec
1.896639027717821E7
</code></pre>
<p>It certainly took a lot less time. Before we go out to celebrate, let's compare the sum of the square root of the primes computed by the different versions. Hmm, we got <code>1.896639027717821E7</code> while the previous two versions printed <code>1.896851199544097E7</code>.</p>
<p>No point running really fast to produce the wrong result.</p>
<p>The culprit is shared mutability. The lambda expression we passed to the <code>forEach</code> method is not a pure-function. When called from multiple threads, the lambdas ran into a race condition while updating the shared mutable variable. Trying to synchronize this access is a wrong solution—we get dragged into the complexity and details we can easily avoid by avoiding explicit mutability.</p>
<p>Even though the functional style is highly capable of parallelization, purity of lambda expressions is vital.</p>
<p>Using impure functions with functional style is like having indigestion when there's surplus gourmet food on the table.</p>
<p>Let's fix the ill-written function composition, to do the right things—avoid mutation, make the lambda expression pure. We'll first create a sequential version.</p>
<pre style="background-color: #f0f0f0;"><code>double sumOfSqrtsOfPrimes =
IntStream.rangeClosed(1, number)
.boxed()
.filter(Sample::isPrime)
.map(Math::sqrt)
.reduce(0.0, Double::sum);
</code></pre>
<p>Doing the right things was not hard. We avoided any explicit mutation in the code. The function function <code>sum</code> of <code>Double</code> is a pure function. We defined a local variable <code>sumOfSqrtsOfPrimes</code> and set it to the result from the function composition. All the functions we used in the function composition are guaranteed by the JDK to be thread-safe.</p>
<p>Let's take a look at how this version performs.</p>
<pre style="background-color: #f0f0f0;"><code>Time Taken: 46.3244 sec
1.896851199544097E7
</code></pre>
<p>First, the result is consistent with the previous sequential versions. The time the code took was similar to the previous ill-written functional style. But, this version is not only easier to parallelize, it's safe as well. Let's do that.</p>
<pre style="background-color: #f0f0f0;"><code>double sumOfSqrtsOfPrimes =
IntStream.rangeClosed(1, number)
.boxed()
.parallel()
.filter(Sample::isPrime)
.map(Math::sqrt)
.reduce(0.0, Double::sum);
</code></pre>
<p>We parallelized this version much like we tried with the earlier version. But, now we're in the right direction. The lambdas given to the <code>filter</code> and the <code>map</code> functions are run concurrently. In addition, the lambda given to the <code>reduce</code> function is also run concurrently, but the <code>reduce</code> function will perform a divide-and-conquer operation and merge the partial results of computations in a thread-safe manner. The result of this computation will not only be faster than the sequential version, but the result be correct as well:</p>
<pre style="background-color: #f0f0f0;"><code>Time Taken: 10.8499 sec
1.8968511995440975E7
</code></pre>
<p>As we get more comfortable and familiar with functional style, we have to remember to keep the lambda expressions pure. In particular, we should avoid shared mutability. I've received emails from programmers asking why their code fails to produce proper result when they add <code>parallel</code>. Often times the problem has been shared mutability from lambda expressions. Let's be careful not to fall into such trap.</p>
<p><A href="http://blog.agiledeveloper.com/2015/12/benefits-of-pure-functions.html">In this series of blogs</A>, we've looked at five benefits so far. In the <A href="http://blog.agiledeveloper.com/2016/06/benefits-of-pure-functions-can-be-lazy.html">next blog we'll look at another benefit: pure functions can be lazy</A>.</p>
</div>Venkat Subramaniamhttp://www.blogger.com/profile/01215171102089313278noreply@blogger.com0