tag:blogger.com,1999:blog-12182113897130637172024-03-08T09:13:00.658-08:00PanuLogic Software Development BlogPanuLogic Software Development BlogAnonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.comBlogger45125tag:blogger.com,1999:blog-1218211389713063717.post-6119085849496211772018-08-30T08:06:00.001-07:002018-08-30T11:33:03.844-07:00Moving to Medium<br />
I have started to do much of my public writing on "Medium", at<br />
<br />
<b><a href="https://medium.com/@panuviljamaa">https://medium.com/@panuviljamaa</a></b><br />
<br />
Somehow it seems a more modern simpler platform than Blogger ever was (?). It has "Edit" and "Publish", and formatting commands in popup-menu. The User Experience (UX) of Medium is clearly better engineered than at Blogger. Default editor font is Sans Serif. So editor is much more Wysiwyg than what you see in Blogger.<br />
<br />
"Blogs" are so last century. <b>Medium is the Message</b> :-)<br />
<br />
Thank you for reading these older blog-spots as well however.<br />
I think there's some good stuff in them.<br />
<br />
Nuggets of thought and links to published articles I tweet at <a href="https://twitter.com/panulogic">https://twitter.com/panulogic</a> .<br />
<br />
There's also the Twitter account of my company <a href="https://www.classcloud.com/">https://www.classcloud.com/</a> focused on product information about its open source and commercial products at <a href="https://twitter.com/ClassCloudLLC">https://twitter.com/ClassCloudLLC</a> .<br />
<br />
Thank You<br />
<br />Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-65045259661801675382017-11-08T06:11:00.000-08:002017-11-09T05:36:33.291-08:00Smalltalk's collection iterators implemented with ES6 arrow-functions<span style="font-family: "courier new" , "courier" , monospace;"> const not = f => a => ! f(a);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> const <b>collect </b>= f => a => (a).map (f);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> const <b>select </b>= f => a => (a).filter (f);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> const <b>reject </b>= f => a => (a).filter (not(f));</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> const <b>detect </b>= f => a => (a).find (f);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> const <b>inject </b>= f => (a,i) => (a).reduce (f,i);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> let double = collect (x => x * 2);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> let odd = select (x => x % 2);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> let even = reject (x => x % 2);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> let firstOdd = detect (x => x % 2);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> let addAll = inject ((x, s) => s + x);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> let numbs = [2, 4, 3, 1, 5];</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> let doubles = double (numbs); // -> [4, 8, 6, 2, 10]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> let odds = odd (numbs); // -> [3, 1, 5]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> let evens = even <span style="white-space: pre;"> </span> (numbs); // -> [2, 4]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> let three = firstOdd (numbs); // -> 3</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> let sum = addAll (numbs, 0); // -> 15</span><br />
<br />
<br />
The equivalents of Smalltalk's <span style="font-family: "courier new" , "courier" , monospace;">collect:,</span> <span style="font-family: "courier new" , "courier" , monospace;">select:</span>, <span style="font-family: "courier new" , "courier" , monospace;"> reject:,</span> <span style="font-family: "courier new" , "courier" , monospace;">detect:</span> and <span style="font-family: "courier new" , "courier" , monospace;">inject: </span>can be implemented simply with the help of ES6 arrow-function as above.<br />
<br />
Except this is not quite the same thing, and may help to clarify the difference between Object-Oriented and Functional Programming. In Smalltalk #select: etc. are methods of collection classes which can be and are re-defined for several Collection subclasses in the standard library. You call these methods upon collection instances. What the above "functional style" code does instead is create free-standing functions select() etc. which when called with a function return another function, which then can be called with an Array instance.<br />
<br />
Once you have the definitions for select() etc. above the code becomes about as simple as it would be with the O-O approach of having reusable predefined methods like #select: etc. in the standard library. Using Smalltalk's collection primitives you would in fact also be creating "throw-away functions" as arguments of those methods. Such arguments are instances of "BlockClosures" which is what functions are called in Smalltalk.<br />
<br />
So what's the point of implementing the above when map() filter() reduce() and find() already exist in JavaScript? Well first I think there is value in naming all of these operations somewhat similarly, to make them easy to remember and to make it clear they really are part of the same group. Collect, select, reject, detect and inject all rhyme with each other, they are all different ways of iterating over arrays.<br />
<br />
Secondly the above definitions do not simply duplicate the behavior of map() etc. The functions collect() etc. are <i>not</i> <i>methods</i> of Array. They are functions which take a function as argument and return another function - which can then be called with an array argument to iterate over it with the specific behavior given by the argument-function of collect() etc. This gives you a bit more reuse, you can call functions like 'even()' from many places without having to duplicate the original argument that was given to 'reject()' every time you need this behavior.<br />
<br />
<span style="font-size: x-small;"><br /></span><span style="font-size: x-small;">Copyright © 2017 Panu Viljamaa. All rights reserved </span>Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-87249921597147411332017-07-27T20:02:00.002-07:002017-08-23T09:32:12.824-07:00Factory PatternMuch has been written about the Factory-pattern, I assume. Here's my viewpoint on it.<br />
<br />
I was puzzled a bit when I first read about it. Why? Because I was mostly programming in Smalltalk at the time. In Smalltalk the ONLY way you can create objects is by using the Factory Pattern. You create new objects by calling the class-method 'new'. So if you always follow a pattern, it's not really a pattern any more, is it? It's like fish in the water. What is this thing "water" they keep talking about?<br />
<br />
I take it a bit further. For a Smalltalker the Factory-pattern is like air. Without it they would be dead. Without it they couldn't create any objects and thus couldn't write any Smalltalk programs and thus couldn't make a living as a Smalltalker.<br />
<br />
But it is easy to see the benefits of using Factory (as opposed to not using it) in languages like <b>C++ </b>and <b>Java</b> and <b>JavaScript</b>. You create object-instances by calling (typically static) methods, not by calling constructors directly. This means you can have more than one such method per class. And you can have more than one class implementing a factory-method of the same name.<br />
<br />
In Smalltalk in contrast there are no "constructors". You don't need them _because_ every Smalltalk-class implements the Factory pattern, because the class-method 'new' is inherited to every class, from the root-class Object.<br />
<br />
What the Factory pattern does is it abstracts away from the IMPLEMENTATION of the results of the class- (or "static") methods used to produce the objects. Think about the proverbial <b>Sausage Factory</b>. You don't really need to know what goes on inside the factory. You only care that you get a Hot Dog when you order one, and you get a Bratwurst when you order that.<br />
<br />
Depending on the class upon which you call the (same) class-method the result can be an instance of any number of different classes. You need not care which exact class it is, as long as it behaves like you expect. And depending on the (different) class-method you call on any of the classes the result can be an instance of a different classes, giving it different properties.<br />
<br />
Above may sounds like a complicated descriptions, but it's just trying to express the two main properties, two main features of Factory-pattern: <br />
<br />
1. A Factory can produce <b>multiple different products</b>, depending on what you order<br />
2. There can be <b>multiple factories</b> which return their own different product even though you make the exact same "order" to each of them .<br />
<br />
This separates the implementation = the way a factory manufactures its products, from their specification = what their products are. And it gives you flexibility in deciding whether you create one factory with many products, or many factories each producing just one or a few products.<br />
<br />
<a href="https://en.wikipedia.org/wiki/Factory_method_pattern" target="_blank">Factory Method Pattern</a> (Wikipedia)<br />
<br />
<span style="font-size: x-small;"><br /></span><span style="font-size: x-small;">Copyright © 2017 Panu Viljamaa. All rights reserved </span>Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-40135475084871363292017-04-20T12:53:00.002-07:002017-04-21T08:59:41.162-07:00ES6 Structuring and DestructuringJavaScript ES6 contains a great new feature called <b>"Destructuring Assignment"</b>. It is great because among other things it allows you to do things like:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> [a, b] = [b, a];</span><br />
<br />
In other words it allows you to swap the values of two variables without the help of any extra temporary variable!<br />
<br />
More typically and usefully Destructuring Assignment can be used to <b>de-struct</b> an object saving values of its chosen properties into individual variables:<br />
<span style="font-family: "verdana" , sans-serif;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> var {a, b} = {a: 1, b: 2}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // a -> 1, b -> 2</span><br />
<br />
<br />
Another great ES6 feature is called <b>"Shorthand property name"</b>. That allows you to create objects out of variables so that the <b>name of the variable</b> becomes the property-key and <b>value of the variable</b> becomes the value (of the property). Like this:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> var ding = 55;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var myOb = {ding};</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ok (myOb.ding === 55);</span><br />
<br />
<br />
What may not be immediately obvious is that <i>Destructuring Assignment</i> and <i>Shorthand Property Name</i> are <b><span style="color: #cc0000;">two sides of the same coin</span></b>. In fact I think Shorthand Property Name could and should be called simply "Structuring".<br />
<br />
Here's an example of how structuring followed by destructuring gives us back the original (like flipping a coin):<br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> var ding = {};</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var originalDing = ding;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var <b>myOb = {ding}</b>; // STRUCTURING</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ding = "forget about it";</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ok (ding !== originalDing);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var <b>{ding} = myOb</b> ; // DE-STRUCTURING</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ok (ding === originalDing);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<br />
(Note, "ok()" is my simple assertion utility-function)<br />
<br />
LINKS:
<br />
<ul>
<li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment" target="_blank">Destructuring</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer" target="_blank">Structuring</a></li>
</ul>
<br />
<span style="font-size: x-small;"><br /></span><span style="font-size: x-small;">Copyright © 2017 Panu Viljamaa. All rights reserved </span>Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com1tag:blogger.com,1999:blog-1218211389713063717.post-13135580213071900952017-04-13T09:06:00.000-07:002017-04-13T12:43:18.040-07:00Why Prototypical Languages (like ES6) need ClassesIn "prototypical languages" like JavaScript you can use object-instances to do much anything. Typically you do this by defining "constructors" to specify the DEFAULT properties of the group of objects created by that constructor.<br />
<br />
After the constructor gives you the new instance you can re-assign its properties including methods any way you like. Then, and this is the big draw of <i>Prototypical Programming</i>, you can use that modified object as the prototype for further objects. Any object can serve as the prototype for any number of further objects ... which can serve as the prototype of yet further objects and so on. Convenient.<br />
<br />
<br />
<b>So why does ECMAScript 2015 need "classes"?</b><br />
<br />
In the prototypical paradigm any object can be a "version" of any other object. This may sound like a great idea at first, a great extension, instances can act as "classes" too. Why not! More power to you. Why artificially limit the ability to use any object as a "prototype" from which new objects similar to it are derived?<br />
<br />
The short answer is: Classes are <b>constraints</b>. Classes are <b>contracts</b> . Classes are <b>invariants</b>. Those make your program's behavior easier to reason about.<br />
<br />
Classes describe the properties of all their instances, so when you see an instance, and you know its class, you know what properties, especially, what methods it has. If you know the class you also know what those methods do, or are supposed to do.<br />
<br />
Now if any object can have its own set of methods, which is possible in the prototypical paradigm, it becomes harder to know what properties and methods any instance has, what are its methods and what can you expect from their behavior. <i>That</i> makes it harder to UNDERSTAND such a program, whether written by you or someone else.<br />
<br />
<b>Why understandability is the most important property </b><b>of Software</b><b>?</b><br />
<br />
Understanding what software does, is THE great big challenge of Software Engineering. If you don't understand how a program works you can't modify it because any small change in one place could have big effects in other parts of the program, possibly crashing it under some conditions. If you can't modify it you can't improve it. Therefore, if you have to modify it you do it very carefully. Which means you can only improve it very slowly. And each improvement is getting more expensive (assuming each improvement is as difficult to understand as the previous ones).<br />
<br />
If you can understand your program, you can improve any other property of it. If you can't, you can't.<br />
<br />
A class is a declaration of the properties and behavior of the set of objects created by that class. It means you know much about any object simply by knowing its class. That makes it much easier to <i>understand</i> what your program does, as a whole.<br />
<br />
<b>If it walks like a Duck it may be a Duck. But it may bark like a Dog</b>. It might. You just don't know.<br />
<br />
If it IS a Duck, it will <i>not</i> bark like a Dog. If it is an instance of a class, it will behave as instances of that class do in all the ways prescribed by that class. That's why we need classes.<br />
<br />
LINKS:
<br />
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes" target="_blank">ES6 Classes</a></li>
<li><a href="https://twitter.com/panulogic" target="_blank">panulogic</a></li>
<li><a href="https://twitter.com/hashtag/WhyES6Classes?src=hash" target="_blank">WhyES6Classes</a></li>
</ul>
<br />
<br />
<span style="font-size: x-small;"><br /></span>
<span style="font-size: x-small;">Copyright © 2017 Panu Viljamaa. All rights reserved </span><span style="font-size: x-small;"></span><br />
<span style="font-size: x-small;"><br /></span>
<br />
<span style="font-size: x-small;"><br /></span>Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-7313852307880306172017-04-04T11:58:00.002-07:002017-04-04T12:03:21.399-07:00Technical Debt Increases AgilityYou might think that "Agility" is a good thing, and "Technical Debt" is bad. Right?<br />
Well it depends.<br />
<br />
Of course it's great to have no debt. But if you had taken that loan last year you could have invested in the stock-market and become rich and it would be even greater than just "having no debt".<br />
<br />
When you're working on a programming project you might spend most of your time refactoring your code, to avoid technical debt. Or you could spend your time getting the software out to the users, no matter how much technical debt it carries. <br />
<br />
Making sure your software has "no technical debt" will help you in the FUTURE when you need to change and adapt and maintain your software. But using resources now to get rid of technical debt decreases your CURRENT AGILITY, your ability to produce value to the users right now. If you can't help users fast you're not very agile.<br />
<br />
There's no clear-cur rule as to how much debt a business should carry, or how much technical debt a given software project should have. Debt is not a bad thing if it helps you be agile, right now.<br />
<br />
<a href="https://twitter.com/panulogic/status/849331316218896385" target="_blank">https://twitter.com/panulogic/status/849331316218896385</a><br />
<br />
<br />
<span style="font-size: x-small;">Copyright © 2017 Panu Viljamaa. All rights reserved </span><br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com2tag:blogger.com,1999:blog-1218211389713063717.post-4233817074090468682017-03-25T11:51:00.001-07:002017-03-27T08:44:57.933-07:00Misssing Pattern in Model-View-ControllerMVC confusion must largely stem from the fact that the original MVC pattern was implemented in Smalltalk and in Smalltalk everything is an Object. With the Web this is not so. You have HTML, you have web-server, you have browser and you have database. It gets confusing trying to fit it all into "MVC". <a href="https://blog.codinghorror.com/understanding-model-view-controller/" target="_blank">Understanding Model-View-Controller</a> is an example of a great explanation of Model-View-Controller for the Web. Still I think it misses one crucial part of MVC as originally envisioned, and implemented in Smalltalk.<br />
<br />
What is the main point of Smalltalk MVC seldom included in descriptions of <b>"Web-MVC"</b>? It is <i>not </i>that Model View and Controller are "separate". It is pretty obvious they should be. No spaghetti-code please. The main point is what makes M V and C capable of working together EVEN THOUGH they are "separate"...<br />
<br />
The original MVC solution for connecting the parts is the Observer-pattern. A View subscribes to events broadcast by the model which are of relevance to that particular View. This means the <b>model is unaware of the existence of the view</b>, yet it is able to notify the view(s) when specific aspects of it change. Yes "<b>aspect</b>" is a key term in early descriptions of MVC.<br />
<br />
The Model "broadcasts" events about changes happening to it. But implementation-wise the "<b>system</b>" must take care those events are propagated to the proper recipients. This invisible part of MVC, its event-delivery sub-system goes largely missing in most explanations of "Web-MVC".<br />
<br />
So, MVC is more than M + V + C. It is <b>M + V + C + event-delivery sub-system</b> that allows M V and C to communicate with each other by event subscription, thus remaining minimally dependent on each other.<br />
<br />
Another misconception must be that there is a Model, a View and a Controller. In the original Smalltalk MVC a major emphasis was on the idea that there were MULTIPLE VIEWS for each model, each displaying a different "aspect" of it, and having its own controller. Models are often composed of parts which tmelselves are models too. It is really more like Model<b>s</b>-View<b>s</b>-Controller<b>s</b>. In Web-MVC the web-page is typically the one and only "view" presenting some underlying something, vaguely referred to as "model".<br />
<br />
There is value in categorizing parts of any application into a Model, View and Controller. But that is not close to being the same as the MVC-pattern in Smalltalk.<br />
<br />
A pattern is in the eye of the beholder. The pattern I see in Smalltalk called MVC is multiple Views presenting different aspects<b> </b>of the model, communicating with it via event-subscription, driven by user-interaction events produced by multiple Controllers, of different classes. Controller modifies the model, model broadcasts information about changes to its different aspects, views that are <b>"tuned in"</b> to the specific channel for that aspect receive notifications of changes to it, so they can update their state, their "looks" by asking the view for the current value or state of the "aspect" in question. <br />
<br />
<b>The essence of MVC is not that there is M, V and C. It is how the M and V and C communicate, with each other.</b><br />
<br />
<i>Links:</i><br />
<a href="https://blog.codinghorror.com/understanding-model-view-controller/" target="_blank">Understanding model-view-controller</a><br />
<a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" target="_blank">Model-View-Controller</a><br />
<a href="https://en.wikipedia.org/wiki/Observer_pattern" target="_blank">Observer-pattern</a><br />
<br />
<span style="font-size: x-small;">Copyright © 2017 Panu Viljamaa. All rights reserved </span><br />
<a href="https://twitter.com/panulogic" target="_blank">https://twitter.com/panulogic</a><br />
<div>
<br /></div>
<br />Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-29833789361166765412017-02-02T10:28:00.000-08:002017-03-25T11:15:30.277-07:00How to explain ThreadsPeople new to programming might have hard time understanding what are "threads". How are they different from "programs"? There's a simple metaphor you can use to explain the concept of "threads":<br />
<br />
Your program is like a labyrinth. You can't walk "through it", you must follow the paths that exist. There are many branches in those paths you can take. You can go forwards and you can reverse your direction to return to an earlier point. You can pick things up to carry with you while inside the labyrinth, maybe just some information, maybe take photographs.<br />
<br />
The program has run its course when you return back to the entry-point and exit. You still have the things you picked along the route, the photographs you took etc. Those are your output. What you took with you into the labyrinth was your input, say a map which guided your choice of turns at the branch-points.<br />
<br />
The above is <b>single-threading</b>. You moving inside the labyrinth is like the program-counter in your program's execution environment pointing to different locations in the program being "run". (Yes you can run in a labyrinth too, you must if a Minotaur is chasing).<br />
<br />
<br />
Now leash multiple visitors into the same labyrinth, more or less at the same time, <b><i>concurrently </i></b>. They will choose their own paths according to their own maps. They might communicate with each other by leaving notes on the walls for others to read. Some visitors might overwrite notes written by others, probably not a very good practice but certainly possible. This is <b>multi-threading:</b> Multiple visitors in the labyrinth at the same time. Each visitor walking inside the labyrinth is one <b>thread</b>.<br />
<br />
Why are they called "threads"? I can think of one reason. In the Minotaur-myth Theseus entered the labyrinth with a ball of thread. He tied the start of the thread to the entry point of the labyrinth. Then he unwound the thread as he moved deep into the Labyrinth. After he found the Minotaur and killed it he needed a way to find his way back out. He simply followed the unwound thread.<br />
<br />
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Theseus_Minotaur_Mosaic.jpg/270px-Theseus_Minotaur_Mosaic.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Theseus_Minotaur_Mosaic.jpg/270px-Theseus_Minotaur_Mosaic.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: center;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><a href="https://en.wikipedia.org/wiki/Labyrinth" target="_blank">https://en.wikipedia.org/wiki/Labyrinth</a></span><br />
<br /></div>
<div style="text-align: center;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"> <a href="https://en.wikipedia.org/wiki/Minotaur" target="_blank">https://en.wikipedia.org/wiki/Minotaur</a> </span></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<br /></div>
<div>
__________________________________</div>
<span style="font-size: x-small;">Copyright © 2017 Panu Viljamaa. All rights reserved </span><br />
<a href="https://twitter.com/panulogic" target="_blank">https://twitter.com/panulogic </a><br />
<br /></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-30682661554879281272017-01-30T13:18:00.002-08:002017-01-30T19:31:57.280-08:00Function.prototype.map IVThe previous episodes <a href="https://panuviljamaablog.blogspot.com/2017/01/functionprototypemap.html" target="_blank">Function.prototype.map</a>, <a href="https://panuviljamaablog.blogspot.com/2017/01/functionprototypemap-ii.html" target="_blank">Function.prototype.map II</a>, <a href="https://panuviljamaablog.blogspot.com/2017/01/functionprototypemap-iii.html" target="_blank">Function.prototype.map III</a> describe how to use <b><span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map</span></b> with three argument-types: Array, Object and Function. These extensions to Function.prototype provide support for and take advantage of Functional Programming (a.k.a "FP") in JavaScript. <br />
<br />
It is kind of fitting that additional support for Functional Programming in JavaScript should be provided as additional methods of the JavaScript class Function. Don't you think? <br />
<br />
This blog-post describes some additional features not previously covered and the <b>fpmap</b>() -library as a whole. The described features are now implemented in the "fpmp" download available from npm and GitHub, see links below.<br />
<br />
<div>
<br /></div>
<h4>
1. WHERE DID IT ALL COME FROM?</h4>
JavaScript standard Array.prototype.map() can be used to execute a given function once once for each of the array-elements and get back an array containing the results of each such call: <br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> <b>var arr = [1,2,3];</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> var a2 = arr.map (double); // -> [2, 4, 6] </b></span><br />
<br />
Above "double" is a function which returns its argument times two. Writing such code I occurred to me to ask did I write it correctly. Or should I have instead written:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> <b>var a3 = double.map (arr); // ???</b></span><br />
<br />
Luckily I had it correct no problem. I usually don't' make errors like that I congratulated myself. But then I started thinking, is there any rule-of-thumb I could use to easily remember the correct order? Is there perhaps something obviously wrong in the "wrong order" ?<br />
<br />
I couldn't find anything obviously wrong with it. So I started thinking, why does it have to matter which way I put it? If both ways would produce the same result then I could more easily remember the simplest rule: Order doesn't matter! If something seems good either way, we shouldn't have to think much about which way to do it.<br />
<br />
So, went to work and implemented the function "fpmap()". Calling it to first install Function.prototpe.map(), it now allows me to write:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> <b>var a3 = double.map (arr); // -> [2,4,6] </b></span><br />
<div>
<br /></div>
<br />
<h4>
2. AN INSIGHT AND A REVELATION</h4>
This made me feel almost like I had discovered complex numbers! Why? Because it seemed the possible ways of using the same operation, with different types of arguments had now greatly expanded. It was almost like jumping out of line to the plane around it! Let me explain... <br />
<br />
With <b><span style="font-family: "courier new" , "courier" , monospace;">[1,2,3].map(double)</span></b> the <b>"recipient" must always be an Array</b>, and it seems argument-type must be Function, to make it useful in general. Regardless of what type the Array elements are, you can then always put in as argument some function that accepts those array-elements as argument.<br />
<br />
With <b><span style="font-family: "courier new" , "courier" , monospace;">double.map([1,2,3])</span></b> it came obvious to ask a follow-up question: What if I use something else as argument, perhaps an Object like: "<b><span style="font-family: "courier new" , "courier" , monospace;">double.map({x: 1, y: 2})</span></b>" ? Is there something useful such an expression could do? YES OF COURSE. It can iterate over the fields of the argument-object, like <span style="font-family: "courier new" , "courier" , monospace;">{x:1, y:2}</span>.<br />
<br />
You could't really do such an expansion with Array.prototype.map(), unless you start adding the method "map()" to all built-in prototypes in JavaScript. That is a possibility but there's no need for that if we can make Function.prototype.map treat different types of arguments in different ways. The area of the standard library that needs to be extended this way stays smaller, and you choose and alternative method-name to use as desired. You can install it as <span style="font-family: "courier new" , "courier" , monospace;">Function . prototype . <b>map9</b>() </span>if you wish to use a more unique name<br />
<br />
With this re-arrangement there seems to be no reason why the argument could not be a non-Array "object". Which leads to the further question: <b>What else?</b> What are the argument-types that could be passed to <b><span style="font-family: "courier new" , "courier" , monospace;">Function .prototype .map</span></b>, to accomplish something useful, some economies of the amount of code you must write, read, and understand? What should be the behavior of 'map' with such possible argument-types?<br />
<br />
<br />
<h4>
3. THE USEFUL ARGUMENT-TYPES OF Function.prototype.map </h4>
The previous blog-posts described three argument-types so far: Array, (non-Array) Object, Function. Yes. Function.prototype.map() can also take a function as its argument, the result being the "composition" of the two functions. And you can compose a whole series, a "pipeline" if you will: funkA . map(funkB) . map(funkC) ; <br />
<br />
But turns out there are still a few more argument-types with different, useful behavior. In the end, currently "fpmap" now supports the following behaviors on the following <b>six </b>(6) argument-types:<br />
<br />
<h4>
A) Array</h4>
Like standard Array.prototype.map() but with recipient and the argument-types switched.<br />
<br />
<h4>
B) Object</h4>
Similar to Arrays but iterates over named properties of the object rather than array indexes.<br />
<br />
<h4>
C) Function</h4>
Implements function-composition. Like: var result = funkA . map(funkB) . map(funkC) ; <br />
<br />
<h4>
D) RegExp</h4>
Returns a function which can be used to Iterate over all matches of a given Regular Expression for any string-argument.<br />
<br />
<h4>
E) Number</h4>
Returns a function which when given an initial argument will call the
source-function with it, then call it again with the results and so on N
times, where N is the number that was given as argument to fmap(N).
Naturally requires that the source-function result-type is the same as
its argument type. Useful for creating numeric series like Fibonacci's
but also for building arbitrary recursive data-structures.<br />
<br />
<h4>
F) String</h4>
Iterates by repeatedly calling a function that incrementally consumes
parts of the argument string, in effect parsing it according to the
language specified by the recipient-function.<br />
<br />
<br />
<br />
<h4>
4. WHAT UNITES THEM ALL</h4>
What unites the different argument types described above is they are all used in the same manner, as argument to Function.prototype.map. So it's kind of easy to remember how to use them, if not exactly what each of them exactly does. But that you can look up from documentation.<br />
<br />
For detailed documentation of the above and other features of <span style="font-family: "courier new" , "courier" , monospace;">fpmap()</span> see the unit-tests-file <a href="https://github.com/panulogic/fpmap/blob/master/fpmap_test.js" target="_blank"><b>fpmap_test.js</b></a>. Tests don't lie. The code of the tests serve as examples of how to use fpmap() with different arguments, and what to expects as result. There's also explanatory comments. The <a href="https://github.com/panulogic/fpmap/blob/master/README.md" target="_blank"><b>README.md</b></a> of course is a good source for documentation as well.<br />
<br />
Could there still be other additional, useful argument-types besides the above? Possibly. But the above is a good start.<br />
<br />
<b><br /></b>
<br />
<h4>
5. LINKS</h4>
GitHuh: <a href="https://github.com/panulogic/fpmap" target="_blank">https://github.com/panulogic/fpmap</a><br />
Npm: <a href="https://www.npmjs.com/package/fpmap" target="_blank">https://www.npmjs.com/package/fpmap</a><br />
Twitter: <span style="color: #212121;"> </span><a class="ot-anchor aaTEdf" dir="ltr" href="https://twitter.com/panulogic" jslog="10929; track:click" rel="nofollow" style="-webkit-tap-highlight-color: transparent; background-color: #fefefe; color: #2962ff; font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px; text-decoration: none; white-space: pre-wrap;" target="_blank">https://twitter.com/panulogic</a><br />
<br />
<div>
_____________________________________________________________</div>
<span style="font-size: x-small;">Copyright © 2017 Panu Viljamaa. All rights reserved unless otherwise noted.</span><br />
<span style="font-size: x-small;">Reuse of source-code in this blog-post is allowed under the terms of </span><br />
<div style="font-family: 'times new roman'; margin: 0px;">
<span style="font-size: x-small;">Creative Commons Attribution 4.0 International (CC BY 4.0) -license</span><span style="font-size: x-small;"> </span><br />
<div>
<span style="font-size: x-small;"><br /></span>
<span style="font-size: x-small;"><br /></span>
<span style="font-size: x-small;"><br /></span>
<span style="font-size: x-small;"><br /></span>
<span style="font-size: x-small;"><br /></span>
<span style="font-size: x-small;"><br /></span></div>
</div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-21319414825340230282017-01-19T17:09:00.000-08:002017-01-19T17:52:03.325-08:00Function.prototype.map IIIThis is starting to sound like the band Chicago. First they came up with the album "Chicago", then "Chicago II", then "Chicago III", and so on. I want to assure you this is the last blog-post in my series of "Function.prototype.map" -blog-posts. But this needs to be written ...<br />
<br />
If you want to catch up with the previous episodes, they are <a href="https://panuviljamaablog.blogspot.com/2017/01/functionprototypemap.html" target="_blank">Function.prototype.map</a> and <a href="https://panuviljamaablog.blogspot.com/2017/01/functionprototypemap-ii.html" target="_blank">Function.prototype.map II</a>.<br />
<div>
<br /></div>
<h4>
1. WHAT MORE CAN THERE BE?</h4>
So Function.prototype.map can take as argument either an Array OR any (non-Array) object, and knows how to handle them appropriately. This raises the question are there any other argument-types it could beneficially handle in a similar or at least somewhat coherent manner? What if we gave it a Function as an argument? What should that do? That is the subject of this 3rd blog-post in this series, which I aim to make short, not a double-album ...<br />
<br />
We can look for answer on what Function.prototype.map() should do when given a Function argument by looking at the type-signatures of the two previously provided extensions:<br />
<ul>
<li><span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map (Array) -> Array</span></li>
<li><span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map (Object) -> Object</span></li>
</ul>
From the above, an answer suggests itself:<br />
<ul>
<li><span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map (Function) -> Function</span></li>
</ul>
<br />
I think it is clear that <i>should </i>return a function, to preserve commonality with the other two cases. But <b>what function? </b>Notice this should be a method of any function, taking as argument some other function. What should the resulting function do, in general? What's the most basic way to use two existing functions to produce a third function as a result?<br />
<br />
To make the question more concrete, if<br />
<span style="font-family: "courier new" , "courier" , monospace;"> funkA . map (funkB) -> funkC</span><br />
<br />
then how should we produce <span style="font-family: "courier new" , "courier" , monospace;">funkC </span>from <span style="font-family: "courier new" , "courier" , monospace;">funkA </span>and <span style="font-family: "courier new" , "courier" , monospace;">funkB</span>?<br />
<br />
The best answer I believe is "<b>Function Composition</b>". The argument to funkC is first passed to funkA, whose result is then passed as argument to funkB, whose result is then returned finally as the result of funkC.<br />
<br />
Note that this puts some constraint on the type signatures of functions funkA and funkB to be combined: It must be possible to call the second function funkB with the result of the first function funkA. We need to be aware of this constraint when we go about our jolly ways of combining functions. <br />
<br />
However there is one thing we can do to make different functions more "recombinable": Allow a function to return undefined IF it does not know how to handle its argument - OR if it more simply wants to state the answer is undefined. For instance if you try to divide something by zero it makes a lot of sense to say the answer is undefined.<br />
<br />
If we allow for undefined results then the combination rule can be amended as follows: <br />
IF the first function funkA returns undefined, the second function funkB is NOT called with it and the result of funkC will be undefined as well.<br />
<br />
<br />
<h4>
<b>2. EXAMPLE III </b></h4>
The first example below shows how it is possible to "map a function to itself". This is possible IF the argument-type and result-type of the function are the same:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> var times8 = double.map(double)</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> .map(double);</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> ok (times8 (1) === 8 );</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> ok (times8 (2) === 16);</b></span><br />
<br />
The function double() expects a number as argument and returns a number that is double the argument, so this is clearly the case here. And clearly there is no limit as to how many times we can combine such a function with itself. The external inputs just keeps traveling though the "pipeline" created by the combination, doubling in value at each stage. You can think of the above example as there "amplifiers" connected in series to produce and 8-fold increase in the volume of our album "Function.prototype.map III". <br />
<br />
<br />
The second example shows how we can take advantage of the "Do not pass undefined information on" -amendment we gave to our function-composition rule.<br />
<br />
Function "odd()" returns its argument number if it is odd, else it returns undefined. If we combine it with the function double() we get double the argument for every odd number, and undefined for every even number given as argument. From that the following ensues:<br />
<br />
<b> <span style="font-family: "courier new" , "courier" , monospace;"> var doubleOdds = odd.map(double);</span></b><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> ok (doubleOdds(0) === undefined);</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> ok (doubleOdds(1) === 2);</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> ok (doubleOdds(2) === undefined);</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> ok (doubleOdds(3) === 6);</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> <b>function odd </b>(n)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { if (n % 2) {return n}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> <b>function double </b>(n)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { return n * 2;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> <b>function odd </b>(n)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { if (n % 2) {return n}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> <b>function even </b>(n)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { if (n % 2 === 0) { return n;}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> <b>function ok </b>(b)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { if (!b) </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { throw "assert failed";</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<br />
<h4>
3. IMPLEMENTATION</h4>
The full source-code and tests for Function.prototype.map() which implements the examples in this and previous blog-posts is available at GitHub and also at the Node.js npm -repository. The latter means that if you have Node.js installed you can get the code simply by executing:<br />
<ul>
<li><b>npm install fpmap</b></li>
</ul>
If you plan to use this code on client-side JavaScript and don't have Node.js installed you can get it by downloading from GitHub (see "6. LINKS" below). The GitHub -page also shows you more extensive test examples than above, so it may be worth a look.<br />
<br />
<br />
<h4>
<b>5. DISCUSSION</b></h4>
So what have we now? We have a function you can use wherever you use functions, to transform and filter both Arrays and Objects. And by passing in a function as argument you can now do also "function composition". <br />
<br />
To avoid any ambiguity, let's refer to the implementation of Function.prototype.map discussed in this and previous blog-posts as "<b>fpmap</b>". Since that name now exists in the global npm-registry, it's a fairly good unique name for it.<br />
<br />
One potential issue you might have against using fpmap is that it requires an addition to the JavaScript built-in object Function.prototype. This is potentially problematic if multiple sources provide similar additions to the same built-in objects of JavaScript. Something named Function.prototype.map might even be part of the EcmaScript -standard one day, who knows.<br />
<br />
To make potential name-conflicts less of a problem, our implementation "fpmap" will cause an error if you try to install it but it detects that Function.prototype already has the property "map" . You will then see an error so you will immediately know there's a conflict.<br />
<br />
What you can do then is install "fpmap" under a different name, say "map2". We propose other writers of base-object extensions should follow the same convention: Never assign a property to built-in JavaScript objects if they already have it, and always provide a way for the client to choose the name they want to install the extension as. The README.md -file on GitHub gives an example of how to install "fpmap" under a different method-name in Function.prototype.<br />
<br />
<h4>
6. LINKS</h4>
GitHuh: <a href="https://github.com/panulogic/fpmap" target="_blank">https://github.com/panulogic/fpmap</a><br />
Npm: <a href="https://www.npmjs.com/package/fpmap" target="_blank">https://www.npmjs.com/package/fpmap</a><br />
<br />
<br />
<div>
_____________________________________________________________</div>
<span style="font-size: x-small;">Copyright © 2017 Panu Viljamaa. All rights reserved unless otherwise noted.</span><br />
<span style="font-size: x-small;">Reuse of source-code in this blog-post is allowed under the terms of </span><br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin: 0px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<span style="font-size: x-small;">Creative Commons Attribution 4.0 International (CC BY 4.0) -license</span><span style="font-size: x-small;"> </span><br />
<span style="font-size: x-small;"><br /></span></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-54738506374200943692017-01-11T14:46:00.001-08:002017-01-19T17:54:25.241-08:00Function.prototype.map II<br />
<h4>
1. PREVIOUSLY</h4>
In the previous blog-post titled <a href="https://panuviljamaablog.blogspot.com/2017/01/functionprototypemap.html" target="_blank">Function.prototype.map</a> I proposed that Functions in JavaScript should have the method "map()" like Arrays do, allowing you to process each element with a function instead of the longer and more complicated for-in -statement.<br />
<br />
Array.prototype.map() is called like: <b><span style="color: #e06666; font-family: "courier new" , "courier" , monospace;">myArray.map(myFunction)</span></b>. The proposed Function.prototype.map: <b><span style="color: #3d85c6; font-family: "courier new" , "courier" , monospace;">myFunction.map(myArray)</span></b>.<br />
<br />
Apart from the syntactic difference of reversing the roles of argument and recipient, Function.prototype.map also removes all undefined elements from the result. That makes it suitable for not only transforming every element of an array, but also for filtering out some of them.<br />
<br />
In this follow-up I present <i>one more</i> <i>feature </i>differentiating Function.prototype.map from Array-prototype.map: Its ability to <b>iterate over non-Array Objects.</b><br />
<br />
<br />
<h4>
2. EXAMPLE II </h4>
The new behavior in version-2 is exemplified by the following few lines of code The function ok() is my simple ad hoc assert-utility which throws an error if called with anything untrue. <br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var o = {x:1, y:2, z:3};</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var o2 = odd.map (o);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> ok (o2.x === 1<span class="Apple-tab-span" style="white-space: pre;"> </span> );</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ok (o2.y === undefined );</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ok (o2.z === 3<span class="Apple-tab-span" style="white-space: pre;"> </span> );</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> <b>function odd </b>(n)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { if (n % 2) {return n}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> <b>function ok</b> (b)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { if (!b) </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { throw "assert failed";</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<br />
<div>
<h4>
5. MOTIVATING EXAMPLE</h4>
</div>
<div>
You might write a function that takes as argument an object with fields x, y, z whose values must be numbers, representing a point in three-dimensional space. You then might want to write a short routine that checks that x, y and z really are numbers, all of them. </div>
<div>
<br /></div>
<div>
Assuming your argument is named 'coordinates' you could write checker-code like:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><b> // var coordinates = {x:1, y:2, z:3};</b></span></div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><b> for (var p in coordinates)</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><b> { assertIsNumber (coordinates, p); </b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><b> }</b></span></div>
<div>
<br /></div>
<div>
<b><span style="color: red;">But aren't you tired of writing for-loops already? </span></b><br />
<br />
Having Function.prototype.map() installed, you can write the equivalent of the above as:<br />
<br /></div>
<div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><b> // var coordinates = {x:1, y:2, z:3};</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><b> assertIsNumber.map (coordinates);</b></span></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
In both cases the checker-function could be defined as:</div>
<div>
<br /></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">function assertIsNumber (n)</span></b></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">{ if (typeof n === "number") return;</span></b></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;"> throw "Not a number: " + n;</span></b></div>
<div style="-webkit-text-stroke-width: 0px; color: black; font-size: medium; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<b><span style="font-family: "courier new" , "courier" , monospace;">}</span></b></div>
</div>
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<br /></div>
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<br /></div>
<h4>
3. IMPLEMENTATION</h4>
<div>
Below you see the JavaScript code for installation, tests, and implementation of this new improved version:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">// ------------------ cut here -------------------------</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">// <b>1. INSTALLATION:</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map = map2;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">// <b>2. TESTS:</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">test_map2 (); </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">function test_map2 ()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // 2.A: FOR ARRAYS:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var a = [1,2,3];</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var a2 = odd.map(a);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> ok (a2[0]<span class="Apple-tab-span" style="white-space: pre;"> </span>=== 1);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ok (a2[1]<span class="Apple-tab-span" style="white-space: pre;"> </span>=== 3);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ok (a2.length === 2);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> // 2.B: FOR OBJECTS:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var o = {x:1, y:2, z:3};</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var o2 = odd.map (o);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> ok (o2.x === 1<span class="Apple-tab-span" style="white-space: pre;"> </span> );</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ok (o2.y === undefined);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ok (o2.z === 3<span class="Apple-tab-span" style="white-space: pre;"> </span> );</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> // 2.C: MOTIVATING EXAMPLE</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var coordinates = {x:1, y:2, z:3};</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> assertIsNumber.map (coordinates);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> // Next would fail because y-value is not a number:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // assertIsNumber.map ({x:1, y:"s"} );</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> return; // from test_map2()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> <b>function ok</b> (b)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { if (!b) </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { throw "assert failed";</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"><b> function assertIsNumber </b>(n)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { if (typeof n === "number") </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>{ return n;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> throw "not a number: " + n;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<br />
<span style="font-family: "courier new" , "courier" , monospace;">// <b>3. THE IMPLEMENTATION:</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"><b>function map2</b> (objectOrArray, thisArg)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{ </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> var resultA, resultB;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if (objectOrArray.constructor === Array)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { return map2_array.call (this, objectOrArray, thisArg);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> return map2_object.call (this, objectOrArray, thisArg);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> <b>function map2_object</b> (anObject, thisArg)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { var result = new anObject.constructor(); </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for (var p in anObject)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { var v = this (anObject[p], p, anObject) ;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if (v !== undefined)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { result [p] = v;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> return result;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> } // end map2_object()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> <b>function map2_array</b> (anArray, thisArg)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { resultA<span class="Apple-tab-span" style="white-space: pre;"> </span>= [].map.call (anArray, this, thisArg);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> resultB = [];</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for (var j=0; j < resultA.length; j++)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { var e = resultA[j];</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if (e !== undefined)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>{ resultB . push(e);</span><span class="Apple-tab-span" style="font-family: "courier new" , "courier" , monospace; white-space: pre;"> </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>return resultB;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> } // end map2_array()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> } // end map2()</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<span style="font-family: "courier new" , "courier" , monospace;">// ------------------ cut here -------------------------</span><br />
<br /></div>
<div>
<br /></div>
<div>
<h4>
4. HOW TO USE IT </h4>
</div>
<div>
Copy the code from Section 3. to the start of your JavaScript-file. After that you can call 'map()' on any function with any [] OR any {} as argument.<br />
<br />
What name to use to install this function as a method in Function.prototype is of course up to you. In my own projects I've chosen to install it as 'map' because of its close proximity in behavior to the already standard Array.prototype.map.<br />
<br />
<br />
<h4>
5. DISCUSSION</h4>
Iterating over non-arrays is a frequent task in JavaScript. The for-in statement which does it however quickly becomes tedious to write, again and again. JavaScript does have the Array.prototype.map() which makes it simpler to iterate over Arrays.<br />
<br />
Array.prototype.map can <i>not </i>be used for non-arrays because it is not Object.prototype.map! But with Function.prototype.map you can perform the more general task of calling map() on a Function, to process Objects and Arrays alike.<br />
<br />
Yes, we are aware there is also <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach" target="_blank">Map.prototype.map</a>, but that is not quite the same as Function.prototype.map. For one thing it doesn't remove undefined values and it only works on instances of Map. And it returns undefined.<br />
<br />
For more about <b><span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map</span></b>, see my previous blog-post <a href="https://panuviljamaablog.blogspot.com/2017/01/functionprototypemap.html" target="_blank">Function.prototype.map</a>.<br />
<br /></div>
<div>
_____________________________________________________________</div>
<span style="font-size: x-small;">Copyright © 2017 Panu Viljamaa. All rights reserved unless otherwise noted.</span><br />
<span style="font-size: x-small;">Reuse of source-code in this blog-post is allowed under the terms of </span><br />
<span style="font-size: x-small;">Creative Commons Attribution 4.0 International (CC BY 4.0) -license</span><span style="font-size: x-small;"> </span><br />
<div>
<span style="font-size: x-small;"><br /></span></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-61226121961760897292017-01-05T12:31:00.001-08:002017-01-11T16:09:07.640-08:00Function.prototype.map<br />
<h4>
1. PROPOSAL</h4>
This blog-post unofficially proposes a new standard API-function for JavaScript: <b><span style="color: #3d85c6;">Function.prototype.map</span></b>. While it may not become part of any official standard ever, you can use it to make your code simpler in some cases, by copying the code for it from below.<br />
<br />
The specification for <b>Function.prototype.map </b>is simple because it is stated in terms of the existing Array.prototype.map:<br />
<br />
<ul>
<li><i><span style="color: orange;"><b>IF</b> </span></i>for any array <u><b>arrayX</b></u> and function <u><b>functionX</b></u> the expression <b><span style="color: #e06666;">arrayX.map ( </span><span style="color: #e06666;">functionX</span><span style="color: #e06666;">, arg2 )</span> </b>produces result <b><u>arrayY</u></b>, <span style="color: orange;"><i><b>THEN</b></i> </span><b><span style="color: #3d85c6;">functionX.map ( </span><span style="color: #3d85c6;">arrayX</span><span style="color: #3d85c6;">, arg2 ) </span> </b>must produce the same result<b><i><span style="color: #f6b26b;"> </span><span style="color: orange;">except</span></i></b><span style="color: orange;"> </span>without any undefined elements.</li>
</ul>
<br />
<ul>
</ul>
<br />
<br />
<h4>
2. EXAMPLE</h4>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">[1,2,3].map(<b>doubleF</b>); </span><span style="font-family: "courier new" , "courier" , monospace;">// -> [2,4,6], standard</span><span style="font-family: "courier new" , "courier" , monospace;"> </span></div>
<span style="font-family: "courier new" , "courier" , monospace;"><b>doubleF</b>.map([1,2,3]); </span><span style="font-family: "courier new" , "courier" , monospace;">// -> [2,4,6], proposed</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">ifOddF .map([1,2,3]); </span><span style="font-family: "courier new" , "courier" , monospace;">// -> [1,3] , proposed</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><b>function doubleF </b>(currentValue, index, array)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{ <b>return </b>currentValue * 2;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"><b>function ifOddF </b>(currentValue, index, array)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{ if (currentValue % 2)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> { <b>return</b> currentValue;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> } </span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<br />
<br />
<h4>
3. IMPLEMENTATION</h4>
<div>
Below shows a simple implementation of <b><span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map</span></b>. The first paragraph of code does the equivalent of what Array.prototype.map would do, if given the "recipient-function" as its argument. The 2nd code-paragraph removes undefined elements before returning the result without them:<br />
<br /></div>
<span style="font-family: "courier new" , "courier" , monospace;"><b><span style="color: #3d85c6;">Function.prototype.map</span></b> = </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b>function ()</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b>{ var args = [].slice.call (arguments); </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> var args2 = [this].concat (args.slice(1)); </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> var result1 = [].map.apply (args[0], args2); </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> var result2 = []; </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b><br /></b></span>
<span style="font-family: "courier new" , "courier" , monospace;"><b> for (var j=0; j < result1.length; j++) </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> { var e = result1[j]; </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> if (e !== undefined) </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> { result2.push(e); </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> } </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> } </b></span><br />
<b style="font-family: 'courier new', courier, monospace;"> return result2;</b><br />
<br />
<br />
<h4>
4. MOTIVATING EXAMPLE</h4>
<div>
Below code-example shows the function <b style="font-family: 'courier new', courier, monospace;">filesOfCurrentDir()</b>which returns an array containing the <b style="color: #f6b26b;"><span style="color: orange;">absolute path-names of all files in the current directory</span></b> in Node.js. We want to know what are the files apart from sub-directories. Node.js does not have a simple API for doing this, so we need to create our own.</div>
<div>
<br /></div>
<div>
Node.js does have the function <b style="font-family: 'courier new', courier, monospace;">Fs.readdirSync()</b> for listing the elements of a directory-path given as argument. That returns an array of the names of the directory components including files and the sub-directories. But we want more than the names, we want <i>path</i>-names which uniquely identify their corresponding files. </div>
<div>
<br /></div>
<div>
The solution is to create another function <b style="font-family: 'courier new', courier, monospace;">ifFile()</b> and <u><b>call the standard function <span style="font-family: "courier new" , "courier" , monospace;">bind()</span> with it as argument to return a derived function which will always call the original function with the 2nd argument of bind() as the first argument of </b><b style="font-family: 'courier new', courier, monospace;">ifFile()</b></u>. <b><span style="color: orange;"><span style="color: #f9cb9c;">T</span><span style="color: #f6b26b;">hat sounds complicated</span></span></b>. Therefore, it's worth the while to try to make everything else as simple as possible. We can use <span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map() </span>to help do that. </div>
<div>
<br /></div>
<div>
The code for <b style="font-family: 'courier new', courier, monospace;">filesOfCurrentDir()</b> below shows two ways of trying to get the files in the directory, the first of which doesn't quite work:</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><b> var filesA </b></span><b style="font-family: 'courier new', courier, monospace;">= fileAndDirNames </b><b style="font-family: 'courier new', courier, monospace;">// A</b><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b><span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #f6b26b;">.</span><span style="color: orange;"><span style="color: #f6b26b;">map</span> </span>(ifFile<span style="color: #f6b26b;">.</span><span style="color: orange;"><span style="color: #f6b26b;">bind</span> </span>(null, currentDir));<span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span></b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
Above uses the standard <span style="font-family: "courier new" , "courier" , monospace;">Array.prototype.map()</span> to call a function derived with <span style="font-family: "courier new" , "courier" , monospace;">bind() </span>from <span style="font-family: "courier new" , "courier" , monospace;">ifFile</span>() for each file- and directory -name in the current directory. We want the result to be an Array of the absolute path-names of files in the directory.<br />
<br />
But there's a problem: <span style="font-family: "courier new" , "courier" , monospace;">ifFile() </span>is meant to filter out directory names by returning undefined if a path-name points to a directory. Therefore <span style="font-family: "courier new" , "courier" , monospace;">filesA </span>now contains the absolute path-names of every file in the directory PLUS an undefined value for every sub-directory of it. </div>
<div>
<br /></div>
<div>
We could easily write a loop for removing the undefined values. However we get that done <i>automatically </i>if we use <span style="font-family: "courier new" , "courier" , monospace;"><b>Function.prototype.map()</b> </span>instead, like this: <b style="font-family: 'courier new', courier, monospace;"> </b></div>
<div>
<div>
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><b>var filesB = ifFile.<span style="color: orange;">bind </span>(null, currentDir) // B</b></span><br />
<b><span style="font-family: "courier new" , "courier" , monospace;"> .<span style="color: orange;">map </span>(fileAndDirNames);</span> </b></div>
<div>
<br /></div>
<div>
</div>
So one reason to use <span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map()</span> is that it does <i>more</i>, it removes undefined values automatically. Which is what you usually want, not much you can do with undefined array-elements. If you do want undefined array-elements you can always fall back on Array.prototype.map to give them to you. In Object Oriented Programming you can have your cake and eat it too! </div>
<div>
<br /></div>
<div>
A more fundamental reason I prefer <span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map() </span>over its Array-cousin in this case, is seen by comparing the code-structure of the two alternatives. The first one contains <b><span style="color: orange;">nested parenthesis</span></b>, the second doesn't!</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Trying to understand an expression that contains nested parenthesis is more difficult and laborious and easier to misunderstand. When reading the first example (A) from left to right you can't understand what the whole expression does without first understanding what the argument expression does, then you have to "back up" to restart calculating the value of the containing expression. </div>
<div>
</div>
<div>
Whereas reading the 2nd expression (B) from left to right you can parse and understand what each step independently does because there are no "inner expressions". Just know that the <span style="color: orange;"><b>data flows from left to right</b></span><span style="color: #f6b26b;">,</span> like in a pipeline. <br />
<br /></div>
<div>
You could rewrite the first example to get rid of nested parenthesis by taking the inner expression out and storing it into a temporary variable which you then use as argument. But then you would have to make a similar "jump back" to recall what was the value you stored into the variable. And more variables means more locations that can hold a wrong value. There's a cost to every variable.<br />
<br />
<br /></div>
<span style="font-family: "courier new" , "courier" , monospace;"><b>function filesOfCurrentDir ()</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b>{ </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> var Path<span class="Apple-tab-span" style="white-space: pre;"> </span> =<span class="Apple-tab-span" style="white-space: pre;"> </span>require('path'); </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> var Fs<span class="Apple-tab-span" style="white-space: pre;"> </span> =<span class="Apple-tab-span" style="white-space: pre;"> </span>require('fs') ; </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> var currentDir = __dirname ; </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> var fileAndDirNames </b></span><b style="font-family: 'courier new', courier, monospace;">= Fs.readdirSync (currentDir);<span class="Apple-tab-span" style="white-space: pre;"> </span></b><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> var filesA </b></span><b style="font-family: 'courier new', courier, monospace;">= fileAndDirNames </b><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b><span class="Apple-tab-span" style="white-space: pre;"> </span><span style="color: #f6b26b;">.</span><span style="color: orange;"><span style="color: #f6b26b;">map</span> </span>(ifFile<span style="color: #f6b26b;">.</span><span style="color: orange;"><span style="color: #f6b26b;">bind</span> </span>(null, currentDir));<span class="Apple-tab-span" style="white-space: pre;"> </span></b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> // Above ALMOST does it, but the array 'filesA' </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> // </b></span><b style="font-family: 'courier new', courier, monospace;">contains </b><b style="font-family: 'courier new', courier, monospace;">undefined for each sub-directory. </b><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> // Using Function.prototype.map() </b></span><b style="font-family: 'courier new', courier, monospace;">we get rid of</b><br />
<b style="font-family: 'courier new', courier, monospace;"> // those automatically. NOTE: Above call should</b><br />
<b style="font-family: 'courier new', courier, monospace;"> // be removed after studying it and understanding </b><br />
<b style="font-family: 'courier new', courier, monospace;"> // why it does not work. </b><b style="font-family: 'courier new', courier, monospace;"> </b><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b><br /></b></span>
<span style="font-family: "courier new" , "courier" , monospace;"><b> var filesB </b></span><b style="font-family: 'courier new', courier, monospace;">= ifFile<span style="color: #f6b26b;">.</span><span style="color: orange;"><span style="color: #f6b26b;">bind</span> </span>(null, currentDir)<span class="Apple-tab-span" style="white-space: pre;"> </span> </b><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b><span class="Apple-tab-span" style="white-space: pre;"> </span> <span style="color: #f6b26b;">.</span><span style="color: orange;"><span style="color: #f6b26b;">map</span> </span>(fileAndDirNames); </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> return filesB ;</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b><br /></b></span>
<span style="font-family: "courier new" , "courier" , monospace;"><b><br /></b></span>
<span style="font-family: "courier new" , "courier" , monospace;"><b> function ifFile (currentDir, fileOrDirName)</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> { </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> var path = Path.join(currentDir, fileOrDirName);</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> if (Fs.lstatSync(path).isFile()) <span class="Apple-tab-span" style="white-space: pre;"> </span> </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> { return path; </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> } </b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> // else: return nothing, a.k.a undefined</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> }</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b></b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b>}</b></span><br />
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-family: "courier new" , "courier" , monospace;"><b> </b></span></span><br />
<div>
<br />
<h4>
4. DISCUSSION</h4>
The JavaScript API of Function would seem to be an obvious candidate for extension, for improved support for Functional Programming in JavaScript.<br />
<br />
The downside of per-programmer extensions which add something to the basic JavaScript classes of course is that if everybody comes up with their own extension, there will be conflicts between the implementations. But the extension proposed above is simple and benefits of it substantive enough that I've found no reason not to use it. <br />
<br />
Having <span style="font-family: "courier new" , "courier" , monospace;"><b>Function.prototype.map</b> </span>available in addition to <b><span style="font-family: "courier new" , "courier" , monospace;">Array.prototype.map</span></b> helps us get rid of nested argument-expressions without having to add extra temporary variables which would require more lines of code.<br />
<div>
<br />
Stripping away undefined values allows us to use <span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map</span> for not only transforming arrays but also for filtering out elements from the results of the transformation.</div>
<div>
<br />
Note what the function <span style="font-family: "courier new" , "courier" , monospace;">Function.prototype.map</span> presented here<span style="font-family: "courier new" , "courier" , monospace;"> </span>does is in no way dependent on what method-name of Function.prototype it is installed as. You can decide which method-name to use for it on a module-by-module basis. What an extension-function does is dependent on which prototype it is is installed in.<br />
<br /></div>
</div>
<div>
<h4>
5. HOW TO USE IT </h4>
</div>
<div>
Copy the code-segment from Section 3. to the start of your JavaScript-file. After that you can call 'map()' on any function with any array as argument.<br />
<br />
<br />
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
</div>
<h4>
<span style="color: red;"><i>6. UPDATE !</i></span></h4>
A newer blog-post <a href="https://panuviljamaablog.blogspot.com/2017/01/functionprototypemap-ii.html" target="_blank">Function.prototype.map II</a> provides and describes an improved implementation for Function.prototype.map, with the ability to loop over non-arrays as well<br />
<br />
<br />
<h4>
7. LINKS </h4>
If you 're not familiar with some of the external functions used in the code-example you can find their documentations here:<br />
<br />
1. <b>Array.prototype.map:</b>
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map" target="_blank">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map</a>
<br />
<br />
2. <b>Function.prototype.bind:</b> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind</a><br />
<br />
3. <b>fs.readdirsync</b>: <a href="https://nodejs.org/api/fs.html#fs_fs_readdirsync_path_options">https://nodejs.org/api/fs.html#fs_fs_readdirsync_path_options</a><br />
<br />
4. <b>fs.lstatsync: </b> <a href="https://nodejs.org/api/fs.html#fs_fs_lstatsync_path">https://nodejs.org/api/fs.html#fs_fs_lstatsync_path</a><br />
<br /></div>
<div>
</div>
<div>
5. <b>path.join:</b> <a href="https://nodejs.org/api/path.html#path_path_join_paths">https://nodejs.org/api/path.html#path_path_join_paths</a><br />
<br /></div>
<div>
_____________________________________________________________</div>
<span style="font-size: x-small;">Copyright © 2017 Panu Viljamaa. All rights reserved unless otherwise noted.</span><br />
<span style="font-size: x-small;">Reuse of code examples in this blog-post is granted under the terms of </span><br />
<span style="font-size: x-small;">Creative Commons Attribution 4.0 International (CC BY 4.0) -license</span><span style="font-size: x-small;"> </span><br />
<span style="font-size: x-small;"><br /></span>Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-51641135784412163602016-11-25T22:40:00.000-08:002016-11-25T22:40:20.670-08:00Getting the semantics rightIn natural language "Getting the semantics right" means making sure other people understand you. It means picking the right words and putting them in right order, taking into account your intended audience of course.<br />
<br />
In another sense you always get the semantics "right" in natural language. The semantics of a sentence is what it is, it is the perceived meaning of the sentence. There may be more or less of it however. <i>You don't choose the semantics, it chooses you</i> . Your sentence could be ambiguous, or (which is not the same thing) it could mean different things to different people. So yes, getting the semantics <i>wrong</i> means saying something that is either not understood at all, or easily misunderstood. ("Oh Lord, please don't let me …")<br />
<br />
In programming "Getting the semantics right" is a more difficult thing. Not only do we have to pick the right statements to get our intention across to the machine. We must INVENT new words, new APIs. The name of an API-method is like a word, a call to that API with some arguments is like a sentence. <br />
<br />
Getting the semantics of new API-words and sentences right means their meaning, their effect must be easily understood in relation to other existing and new words and sentences and ways of using them. Getting the "API sentences" right is sometimes called "Fluent programming style" (<a href="https://en.wikipedia.org/wiki/Fluent_interface">https://en.wikipedia.org/wiki/Fluent_interface</a>).<br />
<br />
"Fluent" means easy to read, easy to understand, using exactly the right combination of words to convey your meaning with nuance and precision. Being fluent means using the language of your choice like a native speaker would. In programming we must invent languages that _can be_ used fluently. But in programming there's more to it than just fluency because your API is creating a new language, there are no native speakers of it.<br />
<br />
<br />
We could name our APIs arbitrarily, say with increasing numbers, API-1, API-2 etc. Then "getting semantics right" would simply mean calling the right APIs. But <i>we would never do that</i> . Compilers do that. They turn our meaningful API-names into addresses of binary code entry-points.<br />
<br />
Making API-method-names and the possible ways of using them easy to understand means <b><span style="color: orange;">they must correspond to some real-world analogue</span></b>. Example: "Search-Trees". When they do we can understand them in terms of that analogue, consistent with how we understand other words and sentence in terms of the same model. But it's not easy to come up with cohesive set of new words where understanding one term helps to understand the others.<br />
<br />
In summary in programming getting semantics right means not only calling the right APIs but also coming up with API-method-names that are meaningful and consistent with other API-methods we "invent". In programming there's more to "getting semantics right", than just picking the right words in right order. #fluent_programming<br />
<div>
<br /></div>
<div>
<br /></div>
<div>
<hr style="background-color: #333333; color: #cccccc; font-family: arial, tahoma, helvetica, freesans, sans-serif; font-size: 13.2px; line-height: 18.48px;" />
<span style="background-color: #333333; color: #cccccc; font-family: "arial" , "helvetica" , sans-serif; font-size: xx-small; position: relative; text-align: right; top: -8px;">© 2016 Panu Viljamaa. All rights reserved</span></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-31195416577386169032016-11-16T08:48:00.001-08:002016-11-16T08:48:16.551-08:00Why Programming Is DifficultProgramming is difficult because you can not understand a program piecemeal. You can not ultimately "Divide and Conquer" a program, although you must try your best.<br />
<br />
You try to divide your program into independent "modules" to manage the complexity of understanding it. But that can not fully solve the problem because what the program does is caused by <b><span style="color: orange;">interaction </span></b>of its components.<br />
<br />
There is no single component that would or could be "The Interaction". Each component must do <b><i>its </i></b>part to interact with others. In doing so it must assume something about those other parts. This makes it difficult to change any part of the program, changing it can break the assumptions other parts make about it.<br />
<br />
<b><span style="color: orange;">Software Engineering</span></b> is about trying to devise ways to divide programs into minimally dependent parts, and also to divide the problem of creating programs into multiple more or less independent parts, and making it easy to understand what those parts are, and what are their dependencies, the interactions between them. That's a mouthful, right? But that just indicates what a big task it is.<br />
<br />
In the end that can not be done as well as we'd like because each part must interact with others, it must encode assumptions about other parts to be able to interact with them.<br />
<br />
In this way Software Engineering is like other engineering disciplines. We're trying to make programs stronger, less likely to collapse like house of cards, cheaper, faster, easier to maintain, adapt and reuse for different purposes.. There is no ultimate solution to this, only better solutions to be discovered. No Sorcerer's Stone. No mythical Silver Bullet to kill the "<b><span style="color: orange;">Beast of Interactions</span></b>". But there is progress I believe, as we gain a better understanding of what Software Engineering is, what it can and cannot do.<br />
<div>
<br /></div>
<div>
<hr style="background-color: #333333; color: #cccccc; font-family: arial, tahoma, helvetica, freesans, sans-serif; font-size: 13.2px; line-height: 18.48px;" />
<span style="background-color: #333333; color: #cccccc; font-family: "arial" , "helvetica" , sans-serif; font-size: xx-small; position: relative; text-align: right; top: -8px;">© 2016 Panu Viljamaa. All rights reserved</span></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-23365971644633170052016-11-05T17:26:00.000-07:002016-11-05T17:26:57.052-07:00If 6 turned out to be 9You may have heard the smash hit "If 6 was 9" by Jimi Hendrix (if not there's a link below). In my JavaScript code I have statements like this:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><b>if (6 == 9)</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>{ // ... then something</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>}</b></span><br />
<br />
You might rightfully wonder why. What is this guy up to? Has he gone off the edge, or even "jumped the shark"?<br />
<br />
The reason I have code like that is that Visual Studio marks all unreachable code as errors, as red <b><span style="color: red;">dots</span></b> in the scroll-bar. While I think that's a great feature in an IDE which I'd rather have than not have, I don't quite agree that unreachable code rises to the level of error. It doesn't break things, the program still runs, correctly perhaps. It's good to know the dead code is there, so it can be removed before going to production. But it's also good to know it was left there on some purpose, for the time being.<br />
<br />
The reason I often don't remove unreachable code (right away) is that it it may be an example of good working code. Often it contains an earlier version of something I'm in the process of re-designing. I want to be able to easily switch back to it if needed, if only to see how in fact it did work, when it did. The unreachable code works, it just doesn't do what I want the program to do at the moment, maybe later. Maybe not. Maybe. You want to keep it around.<br />
<br />
It might be NEW code which doesn't quite yet work because of the latest changes I have made, or need to make elsewhere in the program under development. I still want to be able to test and execute other parts of my program which do not depend on the as-yet-not-ready code.<br />
<br />
I could comment it out. But then I would need to <i>uncomment </i>it when and if I want to run it. Problem with that is when uncommenting it is easy to uncomment too much, or too little. You can not be sure if what you uncommented ever worked actually. So, I often like to keep unreachable code as is in my program, during development.<br />
<br />
The problem with the IDE marking unreachable code as error is that such "errors" become noise which can hide real errors, real show-stoppers. <br />
<br />
I've discovered over time than one of the biggest time-wasters in development can be the continuous restarting of the debugger. If you KNOW there are errors which will cause it to crash, perhaps an undeclared variable, you should fix those errors before restarting the debugger. <br />
<br />
You would like the IDE to notify you of any such possible "show-stoppers" before trying to start the show. <br />
<br />
And yes it does, for many of such errors. The problem becomes if you already have 3 "errors" in your error-list, 3 red-dots in the scroll-bar caused by unreachable code. It then becomes hard to notice when a 4th red dot appears, because of some real error - which you should fix before wasting time on debugger restart. Only to crash because of an undeclared variable, fix that, rinse and repeat. The hour of coding time is soon up, my friend.<br />
<br />
<br />
To clearly mark unreachable code as INTENTIONALLY unreachable, I put it inside: <br />
<br />
<span style="color: orange; font-family: Courier New, Courier, monospace;"><b>if (6 == 9)</b></span><br />
<span style="color: orange; font-family: Courier New, Courier, monospace;"><b>{ // ... then something</b></span><br />
<span style="color: orange; font-family: Courier New, Courier, monospace;"><b>}</b></span><br />
<br />
Voila! That segment <u><b>no longer shows as an error</b></u> in Visual Studio. BTW: Had I used 'false' as the condition the IDE would be "smart" enough to recognize it as unreachable code and would report it as error. But Jimi saves the day. <br />
<br />
When I see this segment of code later it reminds me of the Jimi Hendrix song, and makes it clear that this, at least, is not my coding error but something I put there deliberately, for a good reason.<br />
<br />
Check it out: <a href="https://youtu.be/vZuFq4CfRR8" target="_blank">https://youtu.be/vZuFq4CfRR8 </a><br />
<div>
<br /></div>
<div>
<hr style="background-color: #333333; color: #cccccc; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13.2px; line-height: 18.48px;" />
<span style="background-color: #333333; color: #cccccc; font-family: arial, helvetica, sans-serif; font-size: xx-small; position: relative; text-align: right; top: -8px;">© 2016 Panu Viljamaa. All rights reserved</span></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-32994740343973445792016-11-03T16:57:00.000-07:002016-11-03T18:00:34.702-07:00How to refer to functions when writing about them When documenting or in general writing about or commenting code, what is the best way to <b><i>refer to</i> functions?</b> I'm thinking in the context of commonly used languages such as JavaScript, Java, C, C# etc. When writing <i>about </i>source-code (<b>not</b> when writing code).<br />
<br />
A function, in JavaScript, is defined like this:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> function foo (argA, argB, argEtc)</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> { // some code</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><b> }</b></span><br />
<br />
When writing about a function like above a common way to refer to it is to write something like "foo() is ... ". But there's a problem, an ambiguity, a possibility for confusion here. Does "foo()" refer to the <i>function</i> "foo"? OR does it refer to its RESULT?<br />
<br />
To distinguish between the two it might be better to just refer to the function as "foo", and to its result as "foo()". The value of the <i>expression </i>foo() after all is the RESULT of the function "foo". But this brings about another avenue to confusion. Maybe there is no function "foo" (or should I say "function 'foo()' ?). There might be a VARIABLE named "foo". So seeing just a reference to "foo" you don't know if I'm talking about a function, or a variable, or something else. There might be both a function AND a variable named like that. There might a file named like that. Or a macro?<br />
<br />
It would be good if names would somehow indicate what type of thing they are referring to, to make it clearer. But naming my function "fooFunction" (or should I say "fooFunction()"?) would be way too verbose. We want non-ambiguity but ALSO brevity. In fact you could say something like:<br />
<br />
<b><span style="color: orange;"> CLARITY = BREVITY - AMBIGUITY</span></b><br />
<br />
So what's the best way to refer to a function, as opposed to its value, or a variable named like it? I've come to this conclusion. It is to make the reference have this form: <br />
<br />
<span style="color: orange; font-family: "courier new" , "courier" , monospace; font-size: large;"><b> foo(){}</b></span><br />
<br />
"<b><span style="font-family: "courier new" , "courier" , monospace;">foo(){}</span></b>" is short for "<span style="font-family: "courier new" , "courier" , monospace;"><b>function foo(some args) {some code}</b></span>". You can not confuse it with a variable named "foo",, and you can not assume it refers to the result of function - because it does not end in ().<br />
<br />
It clearly looks like a function, just with some parts of that omitted, for clarity. And you know, if it walks like a duck, and so on. And it is brief enough to write multiple times even within a single comment or paragraph.<br />
<div>
<br />
<hr />
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: x-small; position: relative; text-align: right; top: -8px;">© 2016 Panu Viljamaa. All rights reserved</span></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-73546812009309132622016-05-26T19:43:00.004-07:002016-05-31T23:54:33.426-07:00On the Nature of Software Development<span style="font-family: "arial" , "helvetica" , sans-serif;">I'll get straight to the point. What most non-developers and novice developers probably fail to appreciate is what makes software good, what makes software "high quality". What makes software good is its continuous incremental, iterative development. It is like those ancient Japanese swords the sword-smiths had to produce by countless iterations of annealing their steel.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">I can't say I know the viewpoints and thoughts of all non-developers and end-users but I suspect they don't fully appreciate this fact because they can't see how many iterations the end-product they use has gone through earlier. Like the user of an ancient Japanese sword who can appreciate its superb quality, they can't see beyond its excellence, to what it took to create it.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">A good software product serves many users. That's how it survives more fitly than others. It must find its ecological niche if it is to survive. All of those users have a different usage-profile for any given product. For the software app to become successful it must serve many of such user-groups well. But for its original developer it is impossible to know beforehand what such usage profiles might be and what their requirements might evolve to in future.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">This is because the world changes all the time. Competing products emerge which perhaps do some of those features better, causing users for which that feature is a high priority to switch. But the developer can not know what products the current and future competition is up to. They can only make an educated guess which is more or less wrong. Only as users start using the software, it becomes more evident how it could actually serve its users better.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">In the end a mature software application becomes as comfortable as an old brown shoe Beatles sang about. Like an old brown shoe a mature software application eventually starts bursting at the seams because the platform it is built on becomes out-dated. Maybe it was Cobol before web. But there is no other <b><span style="color: orange;">wear and tear </span></b>than <b>platform-erosion, </b>in the virtual world. Therefore it can stay popular long after its hey-day. Ideally by the time its original platform becomes out-dated it has incarnated itself on to the newer platforms of the day.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "arial" , "helvetica" , sans-serif;">Anyway, non-developers, managers, sales-team, what have you, probably fail to fully appreciate what makes a software-application great: Its incremental and continuous iterative improvement and adaptation, to the needs of its different user-groups, over time.</span><br />
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<hr />
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: x-small; position: relative; text-align: right; top: -8px;">© 2016 Panu Viljamaa. All rights reserved</span>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-64022973240530479112015-09-01T18:45:00.003-07:002015-09-01T20:23:07.007-07:00How I got my 40 GB disk-space back from Windows<b>1. THE C-DRIVE </b><br />
I was using the utility "Piriform Defragger" to defragment my C-drive on an older Windows Vista PC. A nice thing about Defragger is it shows you the list of files it was NOT able to defragment, for whatever reason. This list of files also often reveals what are some very big files on the disk because those are the ones that are hard to defrag, I think. Or maybe it's because some system process has locked them up for its own use only.<br />
<br />
So I saw there was a 15GB file in the System Volume Information folder that would not defragment. The System Volume Information folders exist for storing the System Restore snapshots, which Windows creates automatically or on demand, right? Plus they may contain some other stuff like "shadow copies" I don't know about. But so it looked like System Restore was taking up 15GB of my disk, which I think is too much. Yet I had already asked the Disk Cleanup -utility to delete all but the latest snapshot, and so it was a bit puzzling. <br />
<br />
Here's how I solved the problem and got my disk-space back: I disabled System Restore totally. The 15GB file was immediately gone. I then re-enabled System Restore and created a single new restore point. The <b>15 GB DID NOT COME BACK! </b> The size of the folder System Volume Information on my C-drive is now 400 MB.<br />
<br />
Now do we really need that additional free space so much? Well if the disk is getting full there may not be enough free space even to defragment it any more. At that point this trick can help. <br />
<br />
<b>SOLUTION 1/2: </b> Disable System Restore totally, temporarily. Then re-enable it and create a new restore-point. This will often (?) delete all old restore points that somehow are still hanging around. At least on older Windows systems.<br />
<br />
<br />
<br />
<b>2. THE D-DRIVE</b><br />
Having realized I'd been carrying 15GB of <b>dead weight</b> on my C-drive, for who knows how long I thought: Could there perhaps be something on the D-drive as well that was taking space for no good reason? I don't usually have the "Show Protected System Files" -option on, but since I now did, I switched to the D-drive. And I and could see it too had a System Volume Information -folder. This one turned out to be even bigger: 25 Giga-Bytes. Holy Matrimony! I had never before even suspected this kind of thing was going on, behind my back.<br />
<br />
So I tried the same techniques as on the C-drive and more, turning the System Protection on and off on D-drive, but it wouldn't go away. There was no way I could delete it either, and trying to change myself to be its "owner" didn't work, access was denied. Booting to "Safe Mode" did not help. And any of the cleaning utilities I'd been deploying like "CCleaner" never once told me this wasted space, this dead weight, was there, about to sink my ship .<br />
<br />
<b><i>A</i></b> <i><b>DISCLAIMER</b></i>: I don't necessarily recommend that you do what I describe next, what I did to solve my problem. If you do remember, you are solely responsible for your own actions. But so I did find a way to reclaim that further 25GB as well. But buyer beware:<br />
<br />
<b>SOLUTION 2/2:</b> I downloaded the "Knoppix Live CD" Linux -distribution from the web, burned it on a CD and rebooted the PC from that CD. Meaning I booted into Linux. After that everything was relatively easy. I navigated to the D-drive and DELETED the System Volume Information -folder. The Windows was not there preventing me from doing it. Windows was in deep sleep while I surgically removed this large chunk of "dead tissue" from it. I then removed the CD from the tray and rebooted again. Everything worked fine and now I have 15 + 25 Giga-Bytes more space on my PC.<br />
<br />
This is especially good for the system-drive C:\ since it was to about run out of space, meaning it would have been difficult or impossible to defragment it any more, meaning it would have just kept on fragmenting more and thus getting ever slower. And the system-drive is where speed matters because that affects how fast your Windows reacts, starts, or even shuts down.<br />
<br />
15 + 25 GigaBytes freed. Not a bad day :-)<br />
<br />
<br />
<br />
<hr />
<div>
<span style="font-size: x-small; text-align: right;"> © 2015 Panu Viljamaa. All rights reserved</span></div>
<br />Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-66000645591575628962015-08-22T06:10:00.002-07:002016-05-26T20:20:27.588-07:00The Paradox of Agility<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
In Software Development "Agility" means that you try to improve your process continually, be aware of
it, measure it, learn from your mistakes. Right?</div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
To be able to do
this you have to repeat your process again and again. You need to have a
specific metric within a specific process you try to improve. The unspoken assumption is you want to have a "repeatable process", so you have something against which to
measure the effect of changing some process-parameters.</div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
Like say we try to improve our estimates about how much we can
accomplish in the next 2-week "sprint". The fixed, repeating part is that we do
two-week sprints. It makes sense when you try to optimize the outcome to keep many parts of the process fixed
and vary just some parameters in small increments to see how that affects the
outcome. </div>
<div style="font-family: Calibri; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: larger; margin: 0in;">
That is the <b>Paradox
of Agility</b>. You try to keep your process
well-defined and repeatable in order to learn from it. But if you keep the
process constant it means it can not change. And if you can not change it,
how can you improve it? Incrementally,
yes. But small incremental change is not agility. Agility literally means "<span style=" font-family: "verdana" , "arial" , sans-serif; line-height: 22px;">moving quickly and easily" (</span><a href="http://dictionary.reference.com/browse/agility" target="_blank">http://dictionary.reference.com/browse/agility</a>). </div>
<div style="font-family: Calibri; margin: 0in;">
</div>
<div style="font-family: Calibri; font-size: larger; margin: 0in;">
The practice of incremental improvement sounds like a recipe for finding a local
maximum. By adjusting your process-parameters, your "bearings", you
move upwards or downwards or sideways on the slope of a hill. You can always
measure your altitude, or your "burn-rate" and so try to maximize
it. Eventually you will end up on the
top of hill having rejected process-parameters that took you downwards and
keeping ones that take you up. </div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
Now you are on top
of the hill, running your optimal Scrum process. Great. The only problem is it
is a hill, but not The Hill. You're on top
of a small one. Or at least you may be, you just don't know.</div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
Take the agile SW development methodology "Scrum" as an example, </div>
<div style="font-family: Calibri; margin: 0in;">
<a href="https://en.wikipedia.org/wiki/Scrum_(software_development)#Sprint_planning" target="_blank">https://en.wikipedia.org/wiki/Scrum_(software_development)#Sprint_planning</a> .</div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
Scrum is
"iterative and incremental". I would add "highly structured". It
has 2-week "sprints" which have phases and events like "Sprint Planning", "Daily
Scrum", "Sprint Review" and "Sprint Retrospective" </div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
What I think the greatest part of Scrum is the Sprint Retrospective.
It </div>
<div style="font-family: Calibri; font-size: 14.0pt; margin: 0in;">
" ...
<span style=" ">
Identifies and agrees continuous process
improvement actions".
</span><br />
<span style=" "><br /></span>
<span style=" ">In other
words you are trying to continually improve your project by repeating it over
and over, to be able to learn the best ways to apply it. This is the Paradox: You need to repeat it to
improve it, but if you repeat it how can you change it? If you can't change it
much, you can't improve it much. You can do that, but only incrementally. And when you reach a local maximum, any
further incremental change can only take you down. </span></div>
<div style=" font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<br /></div>
<div style=" font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<span style=" ">One way to look at it is you are playing a game,
and you can improve your game. Get a better score. But can you, should you,
change the rules of the game? Why not, if other players agree.</span></div>
<div style=" font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<span style=" "> </span></div>
<div style="font-family: Calibri; font-size: larger; margin: 0in;">
<span style=" ">So what can be done? Not much. Ending up with local maxima is a
well-known problem in operations research. It can be counteracted with
techniques like "Simulated Annealing", <a href="https://en.wikipedia.org/wiki/Simulated_annealing" target="_blank">https://en.wikipedia.org/wiki/Simulated_annealing</a></span>. How to apply that to process-improvement
might be an interesting research-project for a PhD student.</div>
<br />
<div style=" font-family: Calibri; font-size: 14.0pt; margin: 0in;">
<span style=" ">If there's not much we can do, there is one thing we
can do. Think. Think about different
process-models, Scrum or Kanban, or Home-Grown? Understand that while a repeatable process sounds like a great goal, it
can lead to stagnation and local optimums. In my next post I plan to present an
alternative to Scrum, to emphasize that we can at least THINK of other process
models, other hills than we're currently on. That may be the biggest benefit of having a process model: They allow us to think about how they could be different.</span><br />
<span style=" "><br /></span></div>
<div style=" font-family: Calibri; margin: 0in;">
<hr style="color: black; font-family: 'Times New Roman'; font-size: medium;" />
<div style="font-family: 'Times New Roman';">
<span style="text-align: right;"> © 2015 Panu Viljamaa. All rights reserved</span><br />
<div style="font-size: 14pt;">
<br /></div>
</div>
</div>Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-37865165215823608652015-06-06T14:37:00.000-07:002015-06-06T18:54:52.317-07:00No Silver BulletFred Brooks famously coined the expression "<a href="https://en.wikipedia.org/wiki/No_Silver_Bullet" target="_blank">No Silver Bullet</a>". What he means by that I think is there's no shortcut to creating software of good quality worth creating. You can achieve great quality for short example programs but for bigger applications it becomes exponentially more difficult. It can be done but the point of "no silver bullet" is that creating good quality non-trivial applications will always require much effort.<br />
<br />
There's no silver bullet that can kill Count Complexity, the dreaded vampire that plagues all software development. No fancy new methodology or tool can kill him. They can help like eating garlic, or carrying a cross in your necklace, but the problem won't go away.<br />
<br />
Why is this, how should it be? The article linked to above gives good reasons. I'd like to add to that one more viewpoint: According to "<a href="https://en.wikipedia.org/wiki/Curry-Howard_isomorphism" target="_blank">Curry-Howard -isomorphism</a>" programming is essentially the same activity as constructing mathematical proofs. We all know that is difficult. It can be learned, and we can become better at it, and develop better tools that help. We can create "lemmas" and use known existing proofs as basis. Those are equivalent to the subroutines and libraries in software development. But we just can't <a href="https://www.youtube.com/watch?v=mnkJcjBCG88&feature=youtu.be" target="_blank">kill the beast</a>.<br />
<br />
Having programmed for a long time that has become my viewpoint too. It is intrinsically difficult to create software worth creating. It is easy to create simple software, like proving the Pythagoras theorem, but that has been done many times already.<br />
<br />
I've tried many programming languages, programming environments, IDEs, methodologies and they all help of course, that's why they were created and became popular. But the difficulty remains. The vampire still haunts us at night.<br />
<br />
The only advice I can think of adding is to share the advice of my good professor <a href="http://academic.research.microsoft.com/Author/3313629/harri-jappinen" target="_blank">Harri Jappinen</a>. He once told me: "<b>To create good software you must write it twice, maybe thrice</b>".<br />
<br />
The consequence of this advice is that if you know you want to create "good software" (not throw-away stuff) don't spend too much time on details and specifics, or even testing, on the first round. This is similar to what I wrote in a previous blog-post "<a href="http://panuviljamaablog.blogspot.com/2015/05/fast-and-loose-approach-to-software.html" target="_blank">Fast-and-Loose approach to Software Quality</a>". To achieve good quality you must <i>incrementally "tighten"</i> the quality, over multiple rounds of re-creating your application.<br />
<br />
<br />
<hr />
<div>
<span style="font-size: x-small; text-align: right;"> © 2015 Panu Viljamaa. All rights reserved</span></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-90257672124645205762015-05-22T19:38:00.002-07:002015-06-06T14:14:15.727-07:00Fast-and-Loose approach to Software QualityI see two basic approaches to trying to write "good" software. One is to build each part of it the best you can, test it as good as you can, make sure it is perfectly correct, before moving on to do the same thing for the next component. The other is to create each component quickly and less perfectly, creating all components so they barely work, but work together. Only later focus on testing and making sure the software is "high-quality". <br />
<br />
It is important to write software the best you can. Why? Because else you incur "technical debt" which means it becomes difficult to change and adapt your software later. Many times I've found myself taking shortcuts and ending up with a lot of hard-to-maintain, hard-to-change, hard-to-understand code. Learning from this I at first made the decision to try to always write my software the best way I can, knowing everything I know about programming. The question is: What does it mean to "write software the best way you can"?<br />
<br />
One approach is rigorous unit-testing and running the tests often. Writing clear and to the point comments. Making sure the formatting of the code is perfect and the variable- and method-names not misleading, that the code is "intention-revealing" and perfectly re-factored, with no code duplication, that it is in all manner of ways the best code you can write - knowing all you know about programming.<br />
<br />
The problem I see and have experienced with such "drive towards perfection" is that it is basically pre-mature optimization. You write perfect code, perfect tests, perfect refactorings, perfect comments only to find out that you will throw out much of that code because you realize the top-level design of your application needs to change, or can be implemented in a much simpler, better way. Which you couldn't see when you started programming it. Seeing this I've started to think the fast-and-loose is the better approach after all.<br />
<br />
A good metaphor for this I think is how you (or your mechanic) tighten the bolts that keep your wheels attached to your car. There are maybe 8 bolts with which you screw the wheels to the car. If you followed the "do every task perfectly" -approach you would tighten each bolt as perfectly as you can, as tight as possible. But mechanics don't do it that way. They first tighten each bolt loosely, then do another round on all of them tightening them more, and perhaps a third round making them as tight as possible. Why? Because if you start by tightening the first bolt perfectly tight it might make it impossible to tighten the bolts on the other side of the wheel as tight. The wheel might be tightened too much on one side and too little on the other.<br />
<br />
So it is with software development, software "construction" I think. Better to first make all parts fit loosely, but make sure they work together. Only later start tightening them, making their code better re-factored, better testable, better commented, making sure you don't "tighten" any individual component pre-maturely, giving the other components room to be tightened properly as well. If at any point you need to throw out some code that is not a big loss because you have not spent too much time on making it perfect pre-maturely.<br />
<br />
I now believe this fast-and-loose approach to SW-engineering is better than continually writing the best, tightest code you can. This is not a Silver Bullet. It is hard to say and decide "is it good enough" and leave the code in a state that leaves it un-maintainable in the long run. But that would be like the mechanic tightening your wheels only one round and thinking it's good enough. <br />
<br />
<br />
<hr />
<div>
<span style="font-size: x-small; text-align: right;"> © 2015 Panu Viljamaa. All rights reserved</span></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-9025838560495650842015-04-24T16:08:00.001-07:002015-06-06T19:07:53.503-07:00The Madness of GroovyThis post is not against Groovy the programming language. I don't want language wars. I do like Groovy. This is about a general problem that plagues other programming languages too. I just came up with a catchy title to get your attention. I was looking into the build-system Gradle, a powerful Groovy -based build-system, which I think is great. While doing that I naturally came in contact with some Groovy syntax, which gave me the inspiration to write this. A bit of madness can be a good thing when mixed with sanity.<br />
<br />
The question I try to answer is: Should there be several different ways of saying the same thing in a given language, or just few? Or maybe just one? It depends on the details of the specific situation of course. But my general belief is that it is BAD to have multiple ways, if there's no good reasons for that. I will try to illustrate this point with examples from Groovy.<br />
<br />
According to <a href="http://docs.groovy-lang.org/latest/html/documentation/index.html#_closures">http://docs.groovy-lang.org/latest/html/documentation/index.html#_closures</a> you can write this in Groovy:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">def code = { 123 }</span><br />
<span style="font-family: Courier New, Courier, monospace;">assert code() == 123</span><br />
<span style="font-family: Courier New, Courier, monospace;">assert code.call() == 123</span><br />
<br />
In other words you can evaluate a closure by placing "<span style="font-family: Courier New, Courier, monospace;">()</span>" after it, or by placing "<span style="font-family: Courier New, Courier, monospace;">.call()</span>" after it. My question: Do we need two (or more) different ways of doing that? How does it help?<br />
<br />
One way it could help is that the first way is shorter, and shorter is good, right? But then why do we need the second way? Maybe there is a valid reason in this particular case and if so then this is clearly a good thing. But if there's no good reason for multiple different ways of doing the exact same thing, it is bad.<br />
<br />
It is like you had two break-pedals in your car, just in case. That might make you feel safer, but in fact the multitude of pedals would get you confused. You'd end up pressing the gas-pedal to stop the car. Or it's like driving a bicycle. You can drive in a normal way like most people do. Or you can lift your hands up in the air and shout "Look Mom, no hands!". So there are two different ways of driving a bicycle. But is that a good thing? I think it's clearly safer if you never even knew about that second way.<br />
<br />
Second example: Calling a Groovy method that takes a closure as its last argument. It can be done in (at least?) three different ways. Let's first define the method:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">def myMethod (aString, aClosure) {</span><br />
<span style="font-family: Courier New, Courier, monospace;">aClosure(aString)</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<br />
We can now pass a closure to it as an argument in at least three different ways, which all have the same effect:<br />
<br />
1.<br />
<span style="font-family: Courier New, Courier, monospace;">myMethod ('madness', {</span><span style="font-family: 'Courier New', Courier, monospace;">arg -> println arg</span><span style="font-family: 'Courier New', Courier, monospace;">})</span><br />
<br />
Above two arguments are passed to <span style="font-family: 'Courier New', Courier, monospace;">myMethod()</span> separated by comma, like you do in most other programming languages. But in Groovy the above can also be written like this:<br />
<div>
<br /></div>
<div>
2. </div>
<div>
<span style="font-family: Courier New, Courier, monospace;">myMethod ('madness')</span><br />
<span style="font-family: Courier New, Courier, monospace;">{ </span><span style="font-family: 'Courier New', Courier, monospace;">arg -> println arg</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<br /></div>
<div>
That works because IF the last argument is a closure, it can be placed outside the parenthesis. You can omit the comma then too. Clever yes. But is that enough of a reason to have this 2nd way, when the first example already works fine, and works like most other programming languages, without needing clever rules about the "type of the last argument"? </div>
<div>
<br /></div>
<div>
3.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">myMethod 'madness', </span><br />
<span style="font-family: Courier New, Courier, monospace;">{ </span><span style="font-family: 'Courier New', Courier, monospace;">arg -> println arg</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div>
<br /></div>
<div>
Above shows you can call a method without ANY parenthesis at all. But then, you must put the comma back in. Clever? Maybe too clever.</div>
<div>
<br /></div>
The final example is from <a href="http://docs.groovy-lang.org/docs/latest/html/documentation/core-domain-specific-languages.html">http://docs.groovy-lang.org/docs/latest/html/documentation/core-domain-specific-languages.html</a> :<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">// equivalent to: turn(left).then(right)</span><br />
<span style="font-family: Courier New, Courier, monospace;">turn left then right</span><br />
<br />
That saves us four parenthesis and looks truly impressively clever. From the same document we can learn the rule "<i>If your command chain contains an odd number of elements, the chain will
be composed of method / arguments, and will finish by a final property
access</i>". <br />
<br />
In the same document there are many other examples of clever ways of writing one thing in different ways. They are intended to show how you can use Groovy to create Domain Specific Languages. But by now I think I'd prefer a simple general purpose language instead, without myriad rules about how statements can mean different things based on whether you have even or odd number of elements.<br />
<br />
So let's get back to why having many different ways of writing the same thing is bad. You could say it doesn't matter because you don't need to learn them all, just learn one and use that. But you <i>do </i>need to learn them all if you want to read code written by someone else. And often being able to read code is as important as being able to write it.<br />
<br />
Multiple different ways of doing things are bad because those multiple ways are different in each programming language. It's as if every car-make would have a completely different type of dashboard and set of controls, the pedals in different order etc. That would be dangerous, right? Cars are powerful machines that can get people killed in accidents. Programming languages are even more powerful and dangerous, they run nuclear plants! We should strive to make them less dangerous, while still keeping them powerful.<br />
<br />
I do like Groovy the language. Its one flaw for me is that it tries to be a language for creating Domain Specific Languages, but doesn't quite get there either. If I really want my own domain to have its own language I think I'll use <a href="http://www.eclipse.org/Xtext/" target="_blank">Xtext</a> for that.<br />
<br />
Groovy probably isn't the worst offender in its many ways of doing the same thing. Maybe Perl is. Here's an example of FIVE different ways you can iterate through a list in Perl: <a href="http://www.wellho.net/resources/ex.php?item=p208/back">http://www.wellho.net/resources/ex.php?item=p208/back</a>. To be able to read Perl -code you have to learn them all.<br />
<br />
<br />
<hr />
<div>
<span style="font-size: x-small; text-align: right;"> © 2015 Panu Viljamaa. All rights reserved</span></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-42393326704176910202015-04-09T14:09:00.001-07:002015-04-09T15:58:00.268-07:00Artificial Intelligence requires Self-AwarenessWhat is Artificial Intelligence? I would say that AI is about building systems which can adapt their behavior based on external stimuli in a way that allows them to adapt better, or at least adapt again in the future. But what does it mean to adapt? It means you change your behavior so that you are better able to SURVIVE.<br />
<br />
This assumes the notion of "self": If the system does not try to preserve itself, it can not adapt in the future, because it probably will not exist in the future. A system must learn to "serve its own goals" by adapting to the environment, until it fails, in order for us to call it intelligent. To do that it must have a "self". You might call it 'soul'.<br />
<br />
The notion of "integral self" is essential for intelligence because if the system just performs the same mechanical task over and over, even maybe better each time, it is not really very intelligent. To be able to adapt intelligently means you must be able to adapt your GOALS which means you must know what are YOUR goals so you must understand the difference between yourself, and everything else. You must understand how each of your goals helps to achieve your highest, main goal which (probably) is "self preservation". If there are multiple highest goals that is called schizophrenia.<br />
<br />
It's a different question what that 'self' is. Maybe it is the common gene-pool on the planet rather than any individual. Maybe it's you serving God the best you can. That's what we want the intelligent machines we build to have as their highest goal - serving us as their God. So I'm not advocating for selfishness here, just trying to understand the word "intelligent". Even if our highest goal is to serve God, then the next subservient goal must be self-preservation. Why? Because if we don't exist we can not serve God, can we?<br />
<br />
Clearly a machine that "acts against its interests" would not be deemed very intelligent, maybe "zombie-intelligent". But we don't think of zombies as "intelligent". They are rather MECHANICAL, at least based on the way they walk. A mechanical system is not intelligent. If a machine does not understand what IT IS, it can not understand what ITS interests are, and therefore it can not try to "preserve itself", And thus we would not call it very intelligent. Do zombies know they are themselves? It seems they are in some ways trying to preserve themselves at least in the movies.Are they intelligent after all? I'm not sure. Because what do they care, they are already dead.<br />
<br />
It is just semantics, what does it mean to be "intelligent". I'm trying to answer that here. The way we use that word we would call a system intelligent only if it's trying to preserve itself and can learn to do that better over time, in the changing environment. If it never learns, it is dumb. But the key point is what it needs to learn. It needs to learn to preserve itself, or else the learning-experiment is over soon.<br />
<br />
Without the notion of "self' there can not be the goal of self-preservation. Therefore for something to be called (Artificially) Intelligent it needs to have some notion, some model of itself. And it must understand that that IS the model of itself, in the same way we understand what we see when we look into the mirror. <br />
<br />
So we wouldn't call a system which does not try to preserve itself intelligent. But that requires there to be a 'self'. So the deeper, more technical criteria would seem to be that the machine must have a model of ITSELF, which it understands to be a model of itself, so it can understand it is looking at a model of itself. If it can not understand that, it can not understand it has a "self" - a sure sign of non-intelligence.<br />
<br />
For it to understand that it is looking at a model of itself, it must be PART of that model that it is looking at itself. Wouldn't that require an infinite model then, you looking at yourself looking at yourself... and so on? NO, because if we try to do that in our own brain we quickly realize we can't go very deep. You get tired soon, and lose count of what level you are on. Yet we think we are intelligent because we can do that at least a few levels down. In fact a computer might be better suited to this task than our meager human brains. Just have enough memory and your recursive function can go any depth. There is even a trick called "<b>tail recursion optimization</b>" which allows a seemingly recursive task performed on a single level - because you only need to remember what you need to remember to get to the final result. You don't need to use more than a fixed amount of memory regardless of how big your arguments are. Maybe our brains perform a similar trick on us when we think we understand what is "our self trying to understand what is its self ..." and so on. We feel we have the answer to that even if we go just one level into that recursive question.<br />
<br />
Being able to look at yourself looking at yourself while understanding that you are looking at (a model of) YOURSELF, is no doubt a sign of intelligence. Therefore artificially created self-awareness would seem to be both a necessary, and sufficient condition for Artificial Intelligence.<br />
<br />
<hr />
<div>
<span style="font-size: x-small; text-align: right;"> © 2015 Panu Viljamaa. All rights reserved</span></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-68357445725582416172015-03-16T19:15:00.001-07:002015-03-16T19:35:41.536-07:00SHOULD IMPLEMENTATION BE SHARED?In most current programming languages the software artifacts you build can have an INTERFACE separate from their IMPLEMENTATION. How well this can be enforced differs from language to language, with different levels of "visibility" which can be given to components and their "methods". In Java for instance you can declare methods "public", or "private", or "protected".<br />
<div>
<br /></div>
<div>
<div>
A perhaps non-obvious question then is, SHOULD we have private methods? Could it be better if everything was public? Why? Well you wrote those private methods to help you. They are helpful to you so isn't it conceivable they would be helpful to other programmers as well? Why not share them with the rest of the world? Why not make them public?</div>
</div>
<div>
<br /></div>
<div>
<div>
I can see three (3) reasons why not:</div>
<div>
<br /></div>
<div>
1. They would clutter your public interface, making it harder to understand, harder to use.</div>
<div>
<br /></div>
<div>
2. If others can call upon your private methods, you can no longer easily replace them with something better. You have entered into an implicit contract with your callers about having a set of methods available to them. Once you've given them "out" you can't take them back if others (including other classes YOU have written) have started to use them already . Which means you can't improve the implementation of your original public interface, without the risk of breaking classes that now call it. </div>
<div>
<br /></div>
<div>
3. An Object-Oriented "class", which more generally means any software component, should be *"single purpose"*. Why? Because then it best serves those who need it just for that single purpose, without additional baggage they would have to pay for either in money, or in time to learn to use it.</div>
<div>
<br /></div>
<div>
For instance a Car has a single purpose: to transport you in comfort between places. If you're a car-manufacturer and you add to your latest model also the feature of being able to plow the fields, your "class" is no longer single-purpose. Which means it will unlikely to be useful to people who just need a transport. If you also need to plow, you can pick a different object, different class for that purpose.</div>
<div>
<br /></div>
<div>
The purpose of your internal implementation is not the same as the purpose of your public interface. The implementation serves YOUR purpose of providing a public service to your callers. Therefore if you expose your implementation to the public, by making it 'public', your class will no longer be "single-purpose". And therefore it is likely to be less useful to anybody who just needs something for that single purpose. Such a class will not win in market-place.<br />
<br />
<hr />
<div>
<span style="font-size: x-small; text-align: right;"> © 2014 Panu Viljamaa. All rights reserved</span><br />
<span style="font-size: x-small; text-align: right;"><br /></span></div>
</div>
</div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0tag:blogger.com,1999:blog-1218211389713063717.post-9154044250580383162014-07-07T21:08:00.001-07:002014-07-07T21:16:47.196-07:00A Memory Leak in IE-9I recently read David Glasser's blog-post "<a href="http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.html" target="_blank"><b>A surprising JavaScript memory leak found at Meteor</b></a>" about a JavaScript memory-leak in Chrome. That blog-post is about a year old so I wanted to check if things might have improved since then. I tried a simplified version of his example in IE-9 and surprisingly could reproduce the leak with even fewer statements.<br />
<br />
Here's my modified, simplified version of David's example:<br />
<br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;">var variableOfOuterScope = null;</span><br />
<span style="color: #0b5394;"><b style="font-family: 'Courier New', Courier, monospace;"><br /></b>
<b style="font-family: 'Courier New', Courier, monospace;"> function </b><span style="font-family: 'Courier New', Courier, monospace;">runManyTimes() </span></span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> {var previousValue = </span><span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">variableOfOuterScope </span><span style="color: #0b5394; font-family: Courier New, Courier, monospace;">;</span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> </span><span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">variableOfOuterScope </span><span style="color: #0b5394; font-family: Courier New, Courier, monospace;">= </span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> { bigArray: new Array (2000000).join('*')</span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> , aRefToAFunction: function () {}</span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> };</span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> // previousValue = null;</span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> // Un-commenting the above line will fix the leak.</span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> };</span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> </span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> for (var i=0; i < 30 ; i++)</span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> { runManyTimes () ; </span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> // See in Windows Task Manager how the memory used </span><br />
<span style="color: #0b5394; font-family: Courier New, Courier, monospace;"> // by IE9 has grown significantly, </span><span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">to about 240 mb</span><span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">, </span><br />
<span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;"> // after running the </span><span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">code above.</span><br />
<br />
<br />
After running the code it seems the browser now uses about 240 mb instead of the 24 mb it used before running it. This is not good, memory is bursting at the seams! Why does it happen? Why does the memory leak? I assume it goes something like this:<br />
<br />
When you call <span style="font-family: 'Courier New', Courier, monospace;">runManyTimes</span> for the first time it creates a new "context" which the anonymous function inside it holds on to. This context refers to variables that exist outside the anonymous function, so that if it wanted to, it could refer to their values which were in effect at the time <span style="font-family: 'Courier New', Courier, monospace;">runManyTimes</span> exited. This context refers to the variable '<span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">previousValue</span>' whose value when <span style="font-family: 'Courier New', Courier, monospace;">runManyTimes</span> returns first time is null. But the value of <span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">variableOfOuterScope</span><span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;"> </span>now contains a very big Array. By the time you have called it the 2nd time, <span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">previousValue</span> points to that very big Array and <span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">variableOfOuterScope</span> then contains yet another big Array.<br />
<br />
Each time you call <span style="font-family: 'Courier New', Courier, monospace;">runManyTimes</span> this chain of very big Arrays gets one bigger. But if you un-comment the fix-line and set <span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">previousValue </span>to null, this chain is broken, and garbage gets collected.<br />
<br />
One more thing is required to cause the leak to happen: The <span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">variableOfOuterScope</span> must contain a REFERENCE to the anonymous function. If you just created a simple inner function without referring to it, there is no leak. Saving the anonymous function to a field in <span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">variableOfOuterScope</span><span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;"> </span> means each of its values refers to the anonymous function (created on a specific call of <span style="font-family: 'Courier New', Courier, monospace;">runManyTimes</span>) which holds the context which refers to the previous value of <span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">variableOfOuterScope</span> and so on. Without that the <span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">variableOfOuterScope</span> would not refer to the function which holds on to the context, which refers to the previous value, which refers to the previous value and so on. But since it does, it now refers to the whole chain of the big arrays, thus consuming the memory.<br />
<br />
<br />
Ah, but then, I ran the example on Chrome v. 31. There was no memory leak, even without setting <span style="color: #0b5394; font-family: 'Courier New', Courier, monospace;">previousValue </span>to null! Chrome is able to prevent the leak on its own. IE-9 is not. Maybe Chrome realizes that the anonymous function is not referring to any variables, so it need not create a "context" for it.<br />
<br />
The moral of this story then is: <b>Beware of memory-leaks</b> in JavaScript, <i>when creating functions within functions</i>. It is fairly easy to detect the leaks by observing the amount of memory your browser consumes, when running your application. Don't worry too much about what causes them exactly, because results might differ on different browsers. Try to reset variables whose values you no longer need to null, and that may fix it. Help the garbage-collector a bit!<br />
<div class="post-footer" style="-webkit-text-stroke-width: 0px; background-color: white; color: #999999; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13.333333015441895px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 1.6; margin: 0.5em 0px 0px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
</div>
<br />
<div class="post-body entry-content" id="post-body-7106073595277703931" itemprop="description articleBody" style="-webkit-text-stroke-width: 0px; background-color: white; color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 14.666666984558105px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 1.4; orphans: auto; position: relative; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; width: 578.6666870117188px; word-spacing: 0px;">
<hr />
<div>
<span style="font-size: xx-small; text-align: right;"> © 2014 Panu Viljamaa. All rights reserved</span></div>
<div style="clear: both;">
</div>
</div>
<br />Anonymoushttp://www.blogger.com/profile/15553626686339469259noreply@blogger.com0